@@ -1250,14 +1250,34 @@ handleADT caps op args = case args of
12501250
12511251 ascribe nm k = " (as " <> nm <> " " <> smtType k <> " )"
12521252
1253- -- Various casts
1253+ -- | Handle a kind-cast. This function only needs to cover the conversions that the type-safe API can actually
1254+ -- produce; the dynamic 'svFromIntegral' can request other combinations, which we reject with an error.
1255+ --
1256+ -- The type-safe generators of a 'KindCast' are:
1257+ --
1258+ -- * 'sFromIntegral' : @Integral a => SBV a -> SBV b@. The source is 'Integral', so it is always 'KBounded'
1259+ -- or 'KUnbounded'; the target is any @Num@/@SymVal@ kind (bounded, unbounded, real, rational, or float/double/FP).
1260+ -- * 'sRealToSInteger': only ever emits @KReal -> KUnbounded@.
1261+ -- * shift-amount adjustment: only ever emits @KBounded -> KBounded@.
1262+ --
1263+ -- So the reachable (from, to) pairs are exactly:
1264+ --
1265+ -- * @KBounded -> {KBounded, KUnbounded, KReal, KRational, KFloat/KDouble/KFP}@
1266+ -- * @KUnbounded -> {KBounded, KUnbounded, KReal, KRational, KFloat/KDouble/KFP}@
1267+ -- * @KReal -> KUnbounded@
1268+ --
1269+ -- All of these are handled below (float/double/FP targets are routed through 'handleFPCast' via 'tryFPCast'). Note
1270+ -- that a real or rational can never be a source (reals only appear via 'sRealToSInteger', which targets 'KUnbounded';
1271+ -- rationals are not 'Integral'), so those directions are unreachable and left to 'error'.
12541272handleKindCast :: Kind -> Kind -> Text -> Text
12551273handleKindCast kFrom kTo a
12561274 | kFrom == kTo
12571275 = a
12581276 | True
12591277 = case kFrom of
12601278 KBounded s m -> case kTo of
1279+ KReal -> handleKindCast KUnbounded KReal (handleKindCast kFrom KUnbounded a)
1280+ KRational -> handleKindCast KUnbounded KRational (handleKindCast kFrom KUnbounded a)
12611281 KBounded _ n -> fromBV (if s then signExtend else zeroExtend) m n
12621282 KUnbounded -> if s then " (sbv_to_int " <> a <> " )"
12631283 else " (ubv_to_int " <> a <> " )"
@@ -1266,6 +1286,7 @@ handleKindCast kFrom kTo a
12661286 KUnbounded -> case kTo of
12671287 KReal -> " (to_real " <> a <> " )"
12681288 KBounded _ n -> " ((_ int_to_bv " <> showText n <> " ) " <> a <> " )"
1289+ KRational -> " (SBV.Rational " <> a <> " 1)"
12691290 _ -> tryFPCast
12701291
12711292 KReal -> case kTo of
0 commit comments