diff options
| author | Thomas Bauereiss | 2020-03-22 18:21:57 +0000 |
|---|---|---|
| committer | Thomas Bauereiss | 2020-04-21 01:04:21 +0100 |
| commit | 4b6ffe96896f56d538dc9115c1d1b04156ab34a5 (patch) | |
| tree | 1c3dc102e5216986607cddd5ec8f124133a8c57e /src/rewriter.ml | |
| parent | 3d895704db4689f832180782ab30f1805804e2b3 (diff) | |
Be more careful about type annotations in rewrites to Lem
In particular, don't add annotations for types with existentially
quantified variables that only occur in constraints, not in the type,
e.g. {'i1 'i2, 'i1 == div('i2, 8). int('i1)}. These seem to confuse the
type checker when pulled out into the source AST.
Diffstat (limited to 'src/rewriter.ml')
| -rw-r--r-- | src/rewriter.ml | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/src/rewriter.ml b/src/rewriter.ml index 62870083..3b68f493 100644 --- a/src/rewriter.ml +++ b/src/rewriter.ml @@ -91,6 +91,17 @@ let lookup_generated_kid env kid = let generated_kids typ = KidSet.filter is_kid_generated (tyvars_of_typ typ) +let rec is_src_typ typ = + match typ with + | Typ_aux (Typ_tup typs, l) -> List.for_all is_src_typ typs + | _ -> + match destruct_exist typ with + | Some (kopts, nc, typ') -> + let declared_kids = KidSet.of_list (List.map kopt_kid kopts) in + let unused_kids = KidSet.diff declared_kids (tyvars_of_typ typ') in + KidSet.is_empty unused_kids && KidSet.is_empty (generated_kids typ) + | None -> KidSet.is_empty (generated_kids typ) + let resolve_generated_kids env typ = let subst_kid kid typ = subst_kid typ_subst kid (lookup_generated_kid env kid) typ in KidSet.fold subst_kid (generated_kids typ) typ @@ -99,21 +110,31 @@ let rec remove_p_typ = function | P_aux (P_typ (typ, pat), _) -> remove_p_typ pat | pat -> pat -let add_p_typ typ (P_aux (paux, annot) as pat) = - let typ' = resolve_generated_kids (env_of_pat pat) typ in - if KidSet.is_empty (generated_kids typ') then - P_aux (P_typ (typ', remove_p_typ pat), annot) - else pat +let add_p_typ env typ (P_aux (paux, annot) as pat) = + let typ' = resolve_generated_kids env typ in + if is_src_typ typ' then P_aux (P_typ (typ', remove_p_typ pat), annot) else pat let rec remove_e_cast = function | E_aux (E_cast (_, exp), _) -> remove_e_cast exp | exp -> exp -let add_e_cast typ (E_aux (eaux, annot) as exp) = - let typ' = resolve_generated_kids (env_of exp) typ in - if KidSet.is_empty (generated_kids typ') then - E_aux (E_cast (typ', remove_e_cast exp), annot) - else exp +let add_e_cast env typ (E_aux (eaux, annot) as exp) = + let typ' = resolve_generated_kids env typ in + if is_src_typ typ' then E_aux (E_cast (typ', remove_e_cast exp), annot) else exp + +let add_typs_let env ltyp rtyp exp = + let aux pat lhs rhs = + let pat' = add_p_typ env ltyp pat in + (pat', lhs, rhs) + in + match exp with + | E_aux (E_let (LB_aux (LB_val (pat, lhs), lba), rhs), a) -> + let (pat', lhs', rhs') = aux pat lhs rhs in + E_aux (E_let (LB_aux (LB_val (pat', lhs'), lba), rhs'), a) + | E_aux (E_internal_plet (pat, lhs, rhs), a) -> + let (pat', lhs', rhs') = aux pat lhs rhs in + E_aux (E_internal_plet (pat', lhs', rhs'), a) + | _ -> exp let rec small (E_aux (exp,_)) = match exp with | E_id _ |
