Skip to content

Commit e23df09

Browse files
committed
copilot-theorem: Add XEmptyArray and XArray cases for valFromExpr. Refs #589.
Currently, the `Copilot.Theorem.What4.prove` function returns a list of results, where each result contains a `SatResult` that describes whether a property is `Valid`, `Invalid`, or `Unknown`. The `Invalid` result has the limitation that it does not give any information about a specific counterexample that could drive Copilot into falsifying the property, however. This makes it challenging to interpret what the results of prove mean. The `valFromExpr` function (which produces concrete values when making a counterexample) was lacking cases for `XEmptyArray` and `XArray`, so it would fail if the function was called on these values. This commit adds these missing cases, which make use of the `Typed` evidence added to `XEmptyArray` and `XArray` in a previous commit. We do not yet add a case for structs, which prove more challenging.
1 parent 86d7543 commit e23df09

File tree

1 file changed

+29
-7
lines changed
  • copilot-theorem/src/Copilot/Theorem

1 file changed

+29
-7
lines changed

copilot-theorem/src/Copilot/Theorem/What4.hs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ module Copilot.Theorem.What4
4545
, XExpr(..)
4646
) where
4747

48-
import qualified Copilot.Core.Expr as CE
49-
import qualified Copilot.Core.Spec as CS
50-
import qualified Copilot.Core.Type as CT
48+
import qualified Copilot.Core.Expr as CE
49+
import qualified Copilot.Core.Spec as CS
50+
import qualified Copilot.Core.Type as CT
51+
import qualified Copilot.Core.Type.Array as CTA
5152

5253
import qualified What4.Config as WC
5354
import qualified What4.Expr.Builder as WB
@@ -66,6 +67,7 @@ import qualified Data.Map as Map
6667
import Data.Parameterized.NatRepr
6768
import Data.Parameterized.Nonce
6869
import Data.Parameterized.Some
70+
import qualified Data.Parameterized.Vector as V
6971
import GHC.Float (castWord32ToFloat, castWord64ToDouble)
7072
import LibBF (BigFloat, bfToDouble, pattern NearEven)
7173
import qualified Panic as Panic
@@ -387,10 +389,14 @@ expectedBool :: forall m sym a.
387389
expectedBool what xe =
388390
panic [what ++ " expected to have boolean result", show xe]
389391

390-
data CopilotValue a = CopilotValue { cvType :: CT.Type a
391-
, cvVal :: a
392-
}
392+
-- | A Copilot value paired with its 'CT.Type'.
393+
data CopilotValue a where
394+
CopilotValue :: CT.Typed a => CT.Type a -> a -> CopilotValue a
393395

396+
-- | Convert a symbolic 'XExpr' into a concrete 'CopilotValue'.
397+
--
398+
-- Struct values are not currently supported, so attempting to convert an
399+
-- 'XStruct' value will raise an error.
394400
valFromExpr :: forall sym t st fm.
395401
( sym ~ WB.ExprBuilder t st (WB.Flags fm)
396402
, WI.KnownRepr WB.FloatModeRepr fm
@@ -420,7 +426,23 @@ valFromExpr ge xe = case xe of
420426
(fst . bfToDouble NearEven)
421427
fromRational
422428
(castWord64ToDouble . fromInteger . BV.asUnsigned)
423-
_ -> error "valFromExpr unhandled case"
429+
XEmptyArray tp ->
430+
pure $ Some $ CopilotValue (CT.Array @0 tp) (CTA.array [])
431+
XArray es -> do
432+
(someCVs :: V.Vector n (Some CopilotValue)) <- traverse (valFromExpr ge) es
433+
(Some (CopilotValue headTp _headVal), _) <- pure $ V.uncons someCVs
434+
cvs <-
435+
traverse
436+
(\(Some (CopilotValue tp val)) ->
437+
case tp `testEquality` headTp of
438+
Just Refl -> pure val
439+
Nothing -> panic [ "XArray with mismatched element types"
440+
, show tp
441+
, show headTp
442+
])
443+
someCVs
444+
pure $ Some $ CopilotValue (CT.Array @n headTp) (CTA.array (V.toList cvs))
445+
XStruct _ -> error "valFromExpr: Structs not currently handled"
424446
where
425447
fromBV :: forall a w . Num a => BV.BV w -> a
426448
fromBV = fromInteger . BV.asUnsigned

0 commit comments

Comments
 (0)