Skip to content

Commit ff2f442

Browse files
committed
Handle remaining casts
Fixes #804
1 parent d61202b commit ff2f442

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

Data/SBV/SMT/SMTLib2.hs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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'.
12541272
handleKindCast :: Kind -> Kind -> Text -> Text
12551273
handleKindCast 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

SBVTestSuite/TestSuite/Basics/ArithSolver.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,11 +928,21 @@ realRatConvs = [ testCase "realConv1" $ assertIsThm $ respectsLe sRealToSInteger
928928
, testCase "realConv3" $ assertIsThm realFloorCorrect2
929929
, testCase "realConv4" $ assertIsThm realCeilingCorrect
930930
, testCase "realConv5" $ assertIsThm realCeilingCorrect2
931+
931932
, testCase "ratConv1" $ assertIsThm $ respectsLe sRationalToSIntegerRM
932933
, testCase "ratConv2" $ assertIsThm rationalFloorCorrect
933934
, testCase "ratConv3" $ assertIsThm rationalFloorCorrect2
934935
, testCase "ratConv4" $ assertIsThm rationalCeilingCorrect
935936
, testCase "ratConv5" $ assertIsThm rationalCeilingCorrect2
937+
938+
, testCase "convertCov1" $ assertIsSat (\x y -> sFromIntegral @Word8 @Integer x .== y)
939+
, testCase "convertCov2" $ assertIsSat (\x y -> sFromIntegral @Integer @Word8 x .== y)
940+
, testCase "convertCov3" $ assertIsSat (\x y -> sFromIntegral @Integer @AlgReal x .== y)
941+
, testCase "convertCov4" $ assertIsSat (\x y -> sFromIntegral @Integer @Float x .== y)
942+
, testCase "convertCov5" $ assertIsSat (\x y -> sFromIntegral @Word8 @Float x .== y)
943+
, testCase "convertCov6" $ assertIsSat (\x y -> sFromIntegral @Integer @Rational x .== y)
944+
, testCase "convertCov7" $ assertIsSat (\x y -> sFromIntegral @Word8 @AlgReal x .== y)
945+
, testCase "convertCov8" $ assertIsSat (\x y -> sFromIntegral @Word8 @Rational x .== y)
936946
]
937947
where -- (x <= y) ==> (round x <= round y)
938948
respectsLe :: OrdSymbolic a => (SRoundingMode -> a -> SInteger) -> SRoundingMode -> a -> a -> SBool

0 commit comments

Comments
 (0)