Skip to content

Commit 4a209b2

Browse files
authored
Merge pull request #4261 from mtzguido/smtpat-on-fields
Allow SMT patterns in record fields and typeclass methods
2 parents f763443 + 4ddbb74 commit 4a209b2

5 files changed

Lines changed: 84 additions & 17 deletions

File tree

src/typechecker/FStarC.TypeChecker.TcTerm.fst

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -484,13 +484,16 @@ let check_no_smt_theory_symbols (en:env) (t:term) : ML unit =
484484
(group <| separate_map (comma ^^ break_ 1) pp tlist)
485485
]
486486

487-
let check_smt_pat env t bs c : ML unit =
488-
if U.is_smt_lemma t //check patterns cover the bound vars
489-
then match c.n with
490-
| Comp ({effect_args=[_pre; _post; (pats, _)]}) ->
491-
check_pat_fvs t.pos env pats bs;
492-
check_no_smt_theory_symbols env pats
493-
| _ -> failwith "Impossible: check_smt_pat: not Comp"
487+
let check_smt_pat env t : ML unit =
488+
// Check patterns cover the bound vars
489+
if U.is_smt_lemma t then
490+
let bs, c = U.arrow_formals_comp t in
491+
match c.n with
492+
| Comp ({effect_args=[_pre; _post; (pats, _)]}) ->
493+
check_pat_fvs t.pos env pats bs;
494+
check_no_smt_theory_symbols env pats
495+
| _ ->
496+
failwith "Impossible: check_smt_pat: not Comp"
494497

495498
(************************************************************************************************************)
496499
(* Building the environment for the body of a let rec; *)
@@ -1860,7 +1863,7 @@ and tc_value env (e:term) : ML (term
18601863
let e = {U.arrow bs c with pos=top.pos} in
18611864
(* checks the SMT pattern associated with this function is properly defined with regard to context *)
18621865
if not env.phase1 then
1863-
check_smt_pat env e bs c;
1866+
check_smt_pat env e;
18641867
(* taking the maximum of the universes of the computation and of all binders *)
18651868
let u = S.U_max (uc::us) in
18661869
(* create a universe of level u *)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"msg":["Expected failure:","Tactic failed","Could not solve typeclass constraint `mon`"],"level":"Info","range":{"def":{"file_name":"Bug1918.fst","start_pos":{"line":11,"col":13},"end_pos":{"line":11,"col":14}},"use":{"file_name":"Bug1918.fst","start_pos":{"line":11,"col":13},"end_pos":{"line":11,"col":14}}},"number":228,"ctx":["While synthesizing term with a tactic","Running tactic for meta-arg","While typechecking the top-level declaration `let comp2`","While typechecking the top-level declaration `[@@expect_failure] let comp2`"]}
1+
{"msg":["Expected failure:","Tactic failed","Could not solve typeclass constraint `mon`"],"level":"Info","range":{"def":{"file_name":"Bug1918.fst","start_pos":{"line":11,"col":13},"end_pos":{"line":11,"col":14}},"use":{"file_name":"Bug1918.fst","start_pos":{"line":11,"col":13},"end_pos":{"line":11,"col":14}}},"number":228,"ctx":["While synthesizing term with a tactic","Running tactic for meta-arg","While trying to get a subtyping predicate","While typechecking the top-level declaration `let comp2`","While typechecking the top-level declaration `[@@expect_failure] let comp2`"]}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module RecordPat1
2+
3+
noeq
4+
type deq (a:Type) = {
5+
( =? ) : a -> a -> bool;
6+
7+
eq_sound :
8+
(x:a) -> (y:a) ->
9+
Lemma (requires x =? y)
10+
(ensures x == y)
11+
[SMTPat (x =? y)]
12+
}
13+
14+
let test0 #t (d : deq t) (x y : t) =
15+
if d.op_Equals_Question x y then (
16+
d.eq_sound x y;
17+
assert (x == y)
18+
)
19+
20+
let test1 #t (d : deq t) (x y : t) =
21+
if d.op_Equals_Question x y then
22+
assert (x == y)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module RecordPat2
2+
3+
class deq (a:Type) = {
4+
( =? ) : a -> a -> bool;
5+
6+
eq_sound :
7+
(x:a) -> (y:a) ->
8+
Lemma (requires x =? y)
9+
(ensures x == y)
10+
[SMTPat (x =? y)]
11+
}
12+
13+
let test0 #t {| deq t |} (x y : t) =
14+
if x =? y then (
15+
eq_sound x y;
16+
assert (x == y)
17+
)
18+
19+
let test1 #t {| d : deq t |} (x y : t) =
20+
if d.op_Equals_Question x y then
21+
assert (x == y)
22+
23+
let test2 #t {| d : deq t |} (x y : t) =
24+
let _ = d.op_Equals_Question x y in
25+
if x =? y then
26+
assert (x == y)
27+
28+
let test3 #t {| d : deq t |} (x y : t) =
29+
if x =? y then
30+
assert (x == y)

ulib/FStar.Tactics.Typeclasses.fst

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -578,13 +578,25 @@ let mk_class (nm:string) : Tac decls =
578578
mk_arr (ps@(b1::bs')) cod
579579
in
580580
let def =
581-
let bs, body = collect_abs proj_lb.lb_def in
582-
let ps, bs = List.Tot.Base.splitAt (List.Tot.Base.length params) bs in
583-
match bs with
584-
| [] -> fail "mk_class: impossible, no binders"
585-
| b1::bs' ->
581+
if false then
582+
let bs, body = collect_abs proj_lb.lb_def in
583+
let ps, bs = List.Tot.Base.splitAt (List.Tot.Base.length params) bs in
584+
match bs with
585+
| [] -> fail "mk_class: impossible, no binders"
586+
| b1::bs' ->
587+
let b1 = binder_set_meta b1 tcr in
588+
mk_abs (ps@(b1::bs')) body
589+
else
590+
let bs, _cod = collect_arr_bs proj_lb.lb_typ in
591+
let ps, bs = List.Tot.Base.splitAt (List.Tot.Base.length params) bs in
592+
match bs with
593+
| [] -> fail "mk_class: impossible, no binders"
594+
| b1::bs' ->
586595
let b1 = binder_set_meta b1 tcr in
587-
mk_abs (ps@(b1::bs')) body
596+
mk_abs (ps@[b1]) <|
597+
mk_app (Tv_FVar proj_lb.lb_fv)
598+
(L.map (fun p -> (binder_to_term p, Q_Implicit)) ps
599+
@ [binder_to_term b1, Q_Explicit])
588600
in
589601
debug' (fun () -> "def = " ^ term_to_string def);
590602
debug' (fun () -> "ty = " ^ term_to_string ty);
@@ -597,7 +609,7 @@ let mk_class (nm:string) : Tac decls =
597609
let se = pack_sigelt (Sg_Let {isrec=false; lbs=[lb]}) in
598610
let se = set_sigelt_quals to_propagate se in
599611
let se = set_sigelt_attrs ((`tcmethod) :: proj_attrs @ b.attrs) se in
600-
//debug' (fun () -> "trying to return : " ^ term_to_string (quote se));
612+
// debug' (fun () -> "trying to return : " ^ term_to_string (quote se));
601613
se
602614
)
603-
#pop-options
615+
#pop-options

0 commit comments

Comments
 (0)