Skip to content

Commit 16705a3

Browse files
joscohJosh Cohen
andauthored
Fix bug with multi-argument polymorphic datatypes (#357)
*Description of changes:* There is a bug where when a datatype involves multiple polymorphic type arguments, using a constructor that does not involve both of these arguments (e.g. `Either`) gives an invalid SMT encoding. This PR fixes the bug and adds a test case that formerly failed and now passes. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. --------- Co-authored-by: Josh Cohen <cohenjo@amazon.com>
1 parent b49d14a commit 16705a3

3 files changed

Lines changed: 58 additions & 4 deletions

File tree

Strata/DL/SMT/Encoder.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ def defineApp (inBinder : Bool) (tyEnc : String) (op : Op) (tEncs : List String)
202202
if tEncs.isEmpty then
203203
defineTerm inBinder tyEnc s!"(as {name} {tyEnc})"
204204
else
205-
defineTerm inBinder tyEnc s!"({name} {args})"
205+
defineTerm inBinder tyEnc s!"((as {name} {tyEnc}) {args})"
206206
| .datatype_op _ _ =>
207207
defineTerm inBinder tyEnc s!"({encodeOp op} {args})"
208208
| _ =>

StrataTest/Languages/Core/PolymorphicDatatypeTest.lean

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ assert [lValue] (((~Either..l : (arrow (Either int bool) int)) (x : (Either int
176176
#eval Core.typeCheck Options.quiet (TransM.run Inhabited.default (translateProgram eitherUsePgm)).fst
177177

178178
---------------------------------------------------------------------
179-
-- Test 9: Nested Polymorphic Types (Option of List)
179+
-- Test 5: Nested Polymorphic Types (Option of List)
180180
---------------------------------------------------------------------
181181

182182
def nestedPolyPgm : Program :=
@@ -316,4 +316,58 @@ Result: ✅ pass
316316
#guard_msgs in
317317
#eval verify "cvc5" multiInstSMTPgm Inhabited.default Options.quiet
318318

319+
320+
---------------------------------------------------------------------
321+
-- Test 8: Multiple polymorphic arguments, constructor only needs 1
322+
---------------------------------------------------------------------
323+
324+
def eitherHavocPgm : Program :=
325+
#strata
326+
program Core;
327+
328+
datatype Either (a : Type, b : Type) { Left(l: a), Right(r: b) };
329+
330+
procedure TestEitherHavoc() returns ()
331+
spec {
332+
ensures true;
333+
}
334+
{
335+
var x : Either int bool;
336+
337+
x := Left(0);
338+
havoc x;
339+
340+
assume (x == Left(42));
341+
342+
assert [isLeft]: Either..isLeft(x);
343+
assert [notRight]: !Either..isRight(x);
344+
assert [leftVal]: Either..l(x) == 42;
345+
};
346+
#end
347+
348+
/-- info: true -/
349+
#guard_msgs in
350+
#eval TransM.run Inhabited.default (translateProgram eitherHavocPgm) |>.snd |>.isEmpty
351+
352+
/--
353+
info:
354+
Obligation: isLeft
355+
Property: assert
356+
Result: ✅ pass
357+
358+
Obligation: notRight
359+
Property: assert
360+
Result: ✅ pass
361+
362+
Obligation: leftVal
363+
Property: assert
364+
Result: ✅ pass
365+
366+
Obligation: TestEitherHavoc_ensures_0
367+
Property: assert
368+
Result: ✅ pass
369+
-/
370+
#guard_msgs in
371+
#eval verify "cvc5" eitherHavocPgm Inhabited.default Options.quiet
372+
319373
end Strata.PolymorphicDatatypeTest

StrataTest/Languages/Core/SMTEncoderDatatypeTest.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ info: (declare-datatype TestOption (par (α) (
227227
info: (declare-datatype TestOption (par (α) (
228228
(None)
229229
(Some (TestOption..val α)))))
230-
(define-fun t0 () (TestOption Int) (Some 42))
230+
(define-fun t0 () (TestOption Int) ((as Some (TestOption Int)) 42))
231231
-/
232232
#guard_msgs in
233233
#eval format <$> toSMTStringWithDatatypes
@@ -240,7 +240,7 @@ info: (declare-datatype TestList (par (α) (
240240
(Nil)
241241
(Cons (TestList..head α) (TestList..tail (TestList α))))))
242242
(define-fun t0 () (TestList Int) (as Nil (TestList Int)))
243-
(define-fun t1 () (TestList Int) (Cons 1 t0))
243+
(define-fun t1 () (TestList Int) ((as Cons (TestList Int)) 1 t0))
244244
-/
245245
#guard_msgs in
246246
#eval format <$> toSMTStringWithDatatypes

0 commit comments

Comments
 (0)