Skip to content

Commit 8d2a643

Browse files
committed
copilot-theorem: Add Show and ShowF instances for counterexamples. 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 `CounterExample`, `SatResultCex`, and `CopilotValue` data types lack `Show` and `ShowF` instances, which makes it impractical for users to display them. This commit adds `Show` and `ShowF` instances for all three data types so that they can be shown.
1 parent c5ea1c0 commit 8d2a643

File tree

1 file changed

+56
-32
lines changed
  • copilot-theorem/src/Copilot/Theorem

1 file changed

+56
-32
lines changed

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

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ import qualified Data.BitVector.Sized as BV
6969
import Data.Foldable (foldrM)
7070
import Data.List (genericLength)
7171
import qualified Data.Map as Map
72+
import Data.Parameterized.Classes (ShowF)
7273
import Data.Parameterized.NatRepr
7374
import Data.Parameterized.Nonce
7475
import Data.Parameterized.Some
@@ -100,6 +101,7 @@ data SatResult = Valid | Invalid | Unknown
100101
-- each property in a spec. This is largely the same as 'SatResult', except that
101102
-- 'InvalidCex' also records a 'CounterExample'.
102103
data SatResultCex = ValidCex | InvalidCex CounterExample | UnknownCex
104+
deriving Show
103105

104106
-- | Concrete values that cause a property in a Copilot specification to be
105107
-- invalid. As a simple example, consider the following spec:
@@ -218,38 +220,42 @@ data SatResultCex = ValidCex | InvalidCex CounterExample | UnknownCex
218220
-- Be aware that counterexamples involving struct values are not currently
219221
-- supported.
220222
data CounterExample = CounterExample
221-
{ -- | A list of base cases in the proof, where each entry in the list
222-
-- corresponds to a particular time step. For instance, the first element
223-
-- in the list corresponds to the initial time step, the second element in
224-
-- the list corresponds to the second time step, and so on. A 'False' entry
225-
-- anywhere in this list will cause the overall proof to be 'InvalidCex'.
226-
--
227-
-- Because the proof uses @k@-induction, the number of base cases (i.e., the
228-
-- number of entries in this list) is equal to the value of @k@, which is
229-
-- chosen using heuristics.
230-
baseCases :: [Bool]
231-
-- | Whether the induction step of the proof was valid or not. That is,
232-
-- given an arbitrary time step @n@, if the property is assumed to hold at
233-
-- time steps @n@, @n+1@, ..., @n+k@, then this will be @True@ is the
234-
-- property can the be proven to hold at time step @n+k+1@ (and 'False'
235-
-- otherwise). If this is 'False', then the overall proof will be
236-
-- 'InvalidCex'.
237-
, inductionStep :: Bool
238-
-- | The concrete values in the Copilot specification's extern streams that
239-
-- lead to the property being invalid.
240-
--
241-
-- Each key in the 'Map.Map' is the 'CE.Name' of an extern stream paired
242-
-- with a 'StreamOffset' representing the time step. The key's corresponding
243-
-- value is the concrete value of the extern stream at that time step.
244-
, concreteExternValues :: Map.Map (CE.Name, StreamOffset) (Some CopilotValue)
245-
-- | The concrete values in the Copilot specification's streams (excluding
246-
-- extern streams) that lead to the property being invalid.
247-
--
248-
-- Each key in the 'Map.Map' is the 'CE.Id' of a stream paired with a
249-
-- 'StreamOffset' representing the time step. The key's corresponding value
250-
-- is the concrete value of the extern stream at that time step.
251-
, concreteStreamValues :: Map.Map (CE.Id, StreamOffset) (Some CopilotValue)
252-
}
223+
{ -- | A list of base cases in the proof, where each entry in the list
224+
-- corresponds to a particular time step. For instance, the first element
225+
-- in the list corresponds to the initial time step, the second element
226+
-- in the list corresponds to the second time step, and so on. A 'False'
227+
-- entry anywhere in this list will cause the overall proof to be
228+
-- 'InvalidCex'.
229+
--
230+
-- Because the proof uses @k@-induction, the number of base cases (i.e.,
231+
-- the number of entries in this list) is equal to the value of @k@,
232+
-- which is chosen using heuristics.
233+
baseCases :: [Bool]
234+
-- | Whether the induction step of the proof was valid or not. That is,
235+
-- given an arbitrary time step @n@, if the property is assumed to hold
236+
-- at time steps @n@, @n+1@, ..., @n+k@, then this will be @True@ is the
237+
-- property can the be proven to hold at time step @n+k+1@ (and 'False'
238+
-- otherwise). If this is 'False', then the overall proof will be
239+
-- 'InvalidCex'.
240+
, inductionStep :: Bool
241+
-- | The concrete values in the Copilot specification's extern streams
242+
-- that lead to the property being invalid.
243+
--
244+
-- Each key in the 'Map.Map' is the 'CE.Name' of an extern stream paired
245+
-- with a 'StreamOffset' representing the time step. The key's
246+
-- corresponding value is the concrete value of the extern stream at that
247+
-- time step.
248+
, concreteExternValues ::
249+
Map.Map (CE.Name, StreamOffset) (Some CopilotValue)
250+
-- | The concrete values in the Copilot specification's streams
251+
-- (excluding extern streams) that lead to the property being invalid.
252+
--
253+
-- Each key in the 'Map.Map' is the 'CE.Id' of a stream paired with a
254+
-- 'StreamOffset' representing the time step. The key's corresponding
255+
-- value is the concrete value of the extern stream at that time step.
256+
, concreteStreamValues :: Map.Map (CE.Id, StreamOffset) (Some CopilotValue)
257+
}
258+
deriving Show
253259

254260
-- | Attempt to prove all of the properties in a spec via an SMT solver (which
255261
-- must be installed locally on the host). Return an association list mapping
@@ -624,6 +630,24 @@ expectedBool what xe =
624630
data CopilotValue a where
625631
CopilotValue :: CT.Typed a => CT.Type a -> a -> CopilotValue a
626632

633+
instance Show (CopilotValue a) where
634+
showsPrec p (CopilotValue ty val) =
635+
case ty of
636+
CT.Bool -> showsPrec p val
637+
CT.Int8 -> showsPrec p val
638+
CT.Int16 -> showsPrec p val
639+
CT.Int32 -> showsPrec p val
640+
CT.Int64 -> showsPrec p val
641+
CT.Word8 -> showsPrec p val
642+
CT.Word16 -> showsPrec p val
643+
CT.Word32 -> showsPrec p val
644+
CT.Word64 -> showsPrec p val
645+
CT.Float -> showsPrec p val
646+
CT.Double -> showsPrec p val
647+
CT.Array {} -> showsPrec p val
648+
CT.Struct {} -> showsPrec p val
649+
instance ShowF CopilotValue
650+
627651
-- | Convert a symbolic 'XExpr' into a concrete 'CopilotValue'.
628652
--
629653
-- Struct values are not currently supported, so attempting to convert an

0 commit comments

Comments
 (0)