|
| 1 | +module IT = IndexTerms |
| 2 | +module LC = LogicalConstraints |
| 3 | + |
1 | 4 | module Make (AD : Domain.T) = struct |
2 | 5 | module Ctx = Ctx.Make (AD) |
3 | 6 | module Def = Def.Make (AD) |
4 | 7 | module Term = Term.Make (AD) |
5 | 8 |
|
| 9 | + let is_locally_constrained (x : Sym.t) (gt : Term.t) : bool = |
| 10 | + let rec aux (gt : Term.t) : bool = |
| 11 | + let (Annot (gt_, _, _, _)) = gt in |
| 12 | + match gt_ with |
| 13 | + | `Arbitrary | `Symbolic | `Lazy -> false |
| 14 | + | `Return it_val -> Sym.Set.mem x (IT.free_vars it_val) |
| 15 | + | `Asgn ((it_addr, _), _, gt_rest) -> |
| 16 | + Sym.Set.mem x (IT.free_vars it_addr) || aux gt_rest |
| 17 | + | `Assert (lc, gt_rest) -> Sym.Set.mem x (LC.free_vars lc) || aux gt_rest |
| 18 | + | `Call _ -> false |
| 19 | + | `LetStar |
| 20 | + ((_, Annot ((`Arbitrary | `Symbolic | `Lazy | `Call _), _, _, _)), gt_rest) -> |
| 21 | + aux gt_rest |
| 22 | + | `LetStar ((_, Annot (`Map ((y, _y_bt, _it_perm), gt_inner), _, _, _)), gt_rest) -> |
| 23 | + ((not (Sym.equal x y)) && aux gt_inner) || aux gt_rest |
| 24 | + | `LetStar ((_, Annot (`Return it, _, _, _)), gt_rest) -> |
| 25 | + Sym.Set.mem x (IT.free_vars it) || aux gt_rest |
| 26 | + | `LetStar ((_, _), _) -> failwith ("unreachable @ " ^ __LOC__) |
| 27 | + | `ITE (it_if, gt_then, gt_else) -> |
| 28 | + Sym.Set.mem x (IT.free_vars it_if) || aux gt_then || aux gt_else |
| 29 | + | `Map ((_, _, it_perm), gt') -> Sym.Set.mem x (IT.free_vars it_perm) || aux gt' |
| 30 | + | `Instantiate _ -> failwith ("unreachable @ " ^ __LOC__) |
| 31 | + | `Pick gts -> List.exists aux gts |
| 32 | + in |
| 33 | + aux gt |
| 34 | + |
| 35 | + |
6 | 36 | let rec transform_gt (gt : Term.t) : Term.t = |
7 | 37 | let (GenTerms.Annot (gt_, _tag, bt, loc)) = gt in |
8 | 38 | match gt_ with |
9 | 39 | | `Arbitrary | `Lazy | `Symbolic | `Call _ | `Return _ -> gt |
10 | 40 | | `Asgn ((it_addr, sct), it_val, gt_rest) -> |
11 | 41 | Term.asgn_ ((it_addr, sct), it_val, transform_gt gt_rest) () loc |
12 | | - | `LetStar |
13 | | - ((x, (GenTerms.Annot (`Arbitrary, _, inner_bt, inner_loc) as _gt_inner)), gt_rest) |
14 | | - -> |
| 42 | + | `LetStar ((x, GenTerms.Annot (`Arbitrary, _, inner_bt, inner_loc)), gt_rest) |
| 43 | + when not (is_locally_constrained x gt_rest) -> |
15 | 44 | Term.let_star_ ((x, Term.lazy_ () inner_bt inner_loc), transform_gt gt_rest) () loc |
16 | 45 | | `LetStar ((x, gt_inner), gt_rest) -> |
17 | 46 | Term.let_star_ ((x, transform_gt gt_inner), transform_gt gt_rest) () loc |
|
0 commit comments