summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKathy Gray2014-04-15 11:36:37 +0100
committerKathy Gray2014-04-15 11:36:37 +0100
commitb6c01ea4e538cdd3d92f6ca2543e8ea95d542344 (patch)
treea0dc818de6bd470ca0b3741c7d9fedf40da645a9 /src
parent5e9f4c46b55c527fe639ae88a78fd6386c31756b (diff)
Put conditional path information into constraint gathering so that checking uses appropriate information gleaned from pattern matching
Diffstat (limited to 'src')
-rw-r--r--src/initial_check.ml2
-rw-r--r--src/parser.mly2
-rw-r--r--src/pretty_print.ml8
-rw-r--r--src/type_check.ml27
-rw-r--r--src/type_internal.ml19
-rw-r--r--src/type_internal.mli4
6 files changed, 35 insertions, 27 deletions
diff --git a/src/initial_check.ml b/src/initial_check.ml
index 709eb42b..9f1d46d2 100644
--- a/src/initial_check.ml
+++ b/src/initial_check.ml
@@ -676,7 +676,7 @@ let to_ast (default_names : Nameset.t) (kind_env : kind Envmap.t) (typ_env : tan
List.iter
(fun (id,(d,k)) ->
(match !d with
- | (d,false) -> typ_error Unknown "Scattered definition never ended" (Some id) None None
+ | (d,false) -> typ_error Parse_ast.Unknown "Scattered definition never ended" (Some id) None None
| (_, true) -> ()))
partial_defs;
(Defs defs),k_env
diff --git a/src/parser.mly b/src/parser.mly
index 06b26765..3c3cf8e0 100644
--- a/src/parser.mly
+++ b/src/parser.mly
@@ -95,7 +95,7 @@ let mk_namesectn _ = Name_sect_aux(Name_sect_none,Unknown)
let make_range_sugar_bounded typ1 typ2 =
ATyp_app(Id_aux(Id("range"),Unknown),[typ1; typ2;])
let make_range_sugar typ1 =
- make_range_sugar_bounded typ1 (ATyp_aux(ATyp_constant(0), Unknown))
+ make_range_sugar_bounded (ATyp_aux(ATyp_constant(0), Unknown)) typ1
let make_r bot top =
match bot,top with
diff --git a/src/pretty_print.ml b/src/pretty_print.ml
index cfefd4d0..f0dea03f 100644
--- a/src/pretty_print.ml
+++ b/src/pretty_print.ml
@@ -357,7 +357,7 @@ let pp_def ppf d =
| DEF_fundef(f_def) -> pp_fundef ppf f_def
| DEF_val(lbind) -> fprintf ppf "@[<0>%a@]@\n" pp_let lbind
| DEF_reg_dec(dec) -> pp_dec ppf dec
- | _ -> raise (Reporting_basic.err_unreachable Unknown "initial_check didn't remove all scattered Defs")
+ | _ -> raise (Reporting_basic.err_unreachable Parse_ast.Unknown "initial_check didn't remove all scattered Defs")
let pp_defs ppf (Defs(defs)) =
fprintf ppf "@[%a@]@\n" (list_pp pp_def pp_def) defs
@@ -592,9 +592,9 @@ let pp_format_nes nes =
| LtEq(_,n1,n2) -> "(Nec_lteq " ^ pp_format_n n1 ^ " " ^ pp_format_n n2 ^ ")"
| Eq(_,n1,n2) -> "(Nec_eq " ^ pp_format_n n1 ^ " " ^ pp_format_n n2 ^ ")"
| GtEq(_,n1,n2) -> "(Nec_gteq " ^ pp_format_n n1 ^ " " ^ pp_format_n n2 ^ ")"
- | In(_,i,ns) | InS(_,{nexp=Nvar i},ns) |InOpen(_,{nexp=Nvar i},ns)->
+ | In(_,i,ns) | InS(_,{nexp=Nvar i},ns) ->
"(Nec_in \"" ^ i ^ "\" [" ^ (list_format "; " string_of_int ns)^ "])"
- | InS(_,{nexp = Nuvar _},ns) | InOpen(_,{nexp = Nuvar _},ns) ->
+ | InS(_,{nexp = Nuvar _},ns) ->
"(Nec_in \"fresh\" [" ^ (list_format "; " string_of_int ns)^ "])"
)
nes) ^*) "]"
@@ -810,7 +810,7 @@ let pp_lem_def ppf d =
| DEF_fundef(f_def) -> fprintf ppf "(DEF_fundef %a);" pp_lem_fundef f_def
| DEF_val(lbind) -> fprintf ppf "(DEF_val %a);" pp_lem_let lbind
| DEF_reg_dec(dec) -> fprintf ppf "(DEF_reg_dec %a);" pp_lem_dec dec
- | _ -> raise (Reporting_basic.err_unreachable Unknown "initial_check didn't remove all scattered Defs")
+ | _ -> raise (Reporting_basic.err_unreachable Parse_ast.Unknown "initial_check didn't remove all scattered Defs")
let pp_lem_defs ppf (Defs(defs)) =
fprintf ppf "Defs [@[%a@]]@\n" (list_pp pp_lem_def pp_lem_def) defs
diff --git a/src/type_check.ml b/src/type_check.ml
index 2bb5700d..f8a5cb52 100644
--- a/src/type_check.ml
+++ b/src/type_check.ml
@@ -530,8 +530,10 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp
let (cond',_,_,c1,ef1) = check_exp envs bool_t cond in
let then',then_t,then_env,then_c,then_ef = check_exp envs expect_t then_ in
let else',else_t,else_env,else_c,else_ef = check_exp envs expect_t else_ in
+ let t_cs = CondCons((Expr l),c1,then_c) in
+ let e_cs = CondCons((Expr l),[],else_c) in
(E_aux(E_if(cond',then',else'),(l,Some(([],expect_t),Emp_local,[],pure_e))),
- expect_t,Envmap.intersect_merge (tannot_merge (Expr l) d_env) then_env else_env,then_c@else_c@c1,
+ expect_t,Envmap.intersect_merge (tannot_merge (Expr l) d_env) then_env else_env,[t_cs;e_cs],
union_effects ef1 (union_effects then_ef else_ef))
| E_for(id,from,to_,step,order,block) ->
let fb,fr,tb,tr,sb,sr = new_n(),new_n(),new_n(),new_n(),new_n(),new_n() in
@@ -883,15 +885,17 @@ and check_cases envs check_t expect_t pexps : ((tannot pexp) list * typ * nexp_r
| [] -> raise (Reporting_basic.err_unreachable Parse_ast.Unknown "switch with no cases found")
| [(Pat_aux(Pat_exp(pat,exp),(l,annot)))] ->
let pat',env,cs_p,u = check_pattern envs Emp_local check_t pat in
- let (e,t,_,cs2,ef) = check_exp (Env(d_env,Envmap.union_merge (tannot_merge (Expr l) d_env) t_env env)) expect_t exp in
- [Pat_aux(Pat_exp(pat',e),(l,Some(([],t),Emp_local,cs_p@cs2,ef)))],t,cs_p@cs2,ef
+ let e,t,_,cs_e,ef = check_exp (Env(d_env,Envmap.union_merge (tannot_merge (Expr l) d_env) t_env env)) expect_t exp in
+ let cs = [CondCons(Expr l, cs_p, cs_e)] in
+ [Pat_aux(Pat_exp(pat',e),(l,Some(([],t),Emp_local,cs,ef)))],t,cs,ef
| ((Pat_aux(Pat_exp(pat,exp),(l,annot)))::pexps) ->
let pat',env,cs_p,u = check_pattern envs Emp_local check_t pat in
- let (e,t,_,cs2,ef) = check_exp (Env(d_env,Envmap.union_merge (tannot_merge (Expr l) d_env) t_env env)) expect_t exp in
- let (pes,tl,csl,efl) = check_cases envs check_t expect_t pexps in
- ((Pat_aux(Pat_exp(pat',e),(l,(Some(([],t),Emp_local,(cs_p@cs2),ef)))))::pes,
+ let (e,t,_,cs_e,ef) = check_exp (Env(d_env,Envmap.union_merge (tannot_merge (Expr l) d_env) t_env env)) expect_t exp in
+ let cs = CondCons(Expr l,cs_p,cs_e) in
+ let (pes,tl,csl,efl) = check_cases envs check_t expect_t pexps in
+ ((Pat_aux(Pat_exp(pat',e),(l,(Some(([],t),Emp_local,[cs],ef)))))::pes,
tl,
- csl@cs_p@cs2,union_effects efl ef)
+ cs::csl,union_effects efl ef)
and check_lexp envs is_top (LEXP_aux(lexp,(l,annot))) : (tannot lexp * typ * tannot emap * tag *nexp_range list *effect ) =
let (Env(d_env,t_env)) = envs in
@@ -1242,12 +1246,13 @@ let check_fundef envs (FD_aux(FD_function(recopt,tannotopt,effectopt,funcls),(l,
let check t_env =
List.split
(List.map (fun (FCL_aux((FCL_Funcl(id,pat,exp)),l)) ->
- let (pat',t_env',constraints',t') = check_pattern (Env(d_env,t_env)) Emp_local param_t pat in
+ let (pat',t_env',cs_p,t') = check_pattern (Env(d_env,t_env)) Emp_local param_t pat in
(*let _ = Printf.printf "about to check that %s and %s are consistent\n" (t_to_string t') (t_to_string param_t) in*)
- let exp',_,_,constraints,ef = check_exp (Env(d_env,Envmap.union_merge (tannot_merge (Expr l) d_env) t_env t_env')) ret_t exp in
+ let exp',_,_,cs_e,ef = check_exp (Env(d_env,Envmap.union_merge (tannot_merge (Expr l) d_env) t_env t_env')) ret_t exp in
(*let _ = Printf.printf "checked function %s : %s -> %s\n" (id_to_string id) (t_to_string param_t) (t_to_string ret_t) in*)
(*let _ = (Pretty_print.pp_exp Format.std_formatter) exp' in*)
- (FCL_aux((FCL_Funcl(id,pat',exp')),l),((constraints'@constraints),ef))) funcls) in
+ let cs = [CondCons(Fun l,cs_p,cs_e)] in
+ (FCL_aux((FCL_Funcl(id,pat',exp')),l),(cs,ef))) funcls) in
match (in_env,tannot) with
| Some(Some( (params,u),Spec,constraints,eft)), Some( (p',t),_,c',eft') ->
(*let _ = Printf.printf "Function %s is in env\n" id in*)
@@ -1256,7 +1261,7 @@ let check_fundef envs (FD_aux(FD_function(recopt,tannotopt,effectopt,funcls),(l,
let t_env = if is_rec then t_env else Envmap.remove t_env id in
let funcls,cs_ef = check t_env in
let cs,ef = ((fun (cses,efses) -> (List.concat cses),(List.fold_right union_effects efses pure_e)) (List.split cs_ef)) in
- let cs' = resolve_constraints cs in
+ let cs' = resolve_constraints cs@constraints in
let tannot = check_tannot l tannot cs' ef in
(FD_aux(FD_function(recopt,tannotopt,effectopt,funcls),(l,tannot))),
Env(d_env,Envmap.insert t_env (id,tannot))
diff --git a/src/type_internal.ml b/src/type_internal.ml
index 1aa31473..85537b83 100644
--- a/src/type_internal.ml
+++ b/src/type_internal.ml
@@ -70,7 +70,7 @@ type tag =
type constraint_origin =
| Patt of Parse_ast.l
| Expr of Parse_ast.l
- | Abre of Parse_ast.l
+ | Fun of Parse_ast.l
| Specc of Parse_ast.l
(* Constraints for nexps, plus the location which added the constraint *)
@@ -80,7 +80,7 @@ type nexp_range =
| GtEq of constraint_origin * nexp * nexp
| In of constraint_origin * string * int list
| InS of constraint_origin * nexp * int list (* This holds the given value for string after a substitution *)
- | InOpen of constraint_origin * nexp * int list (* This holds a non-exhaustive value/s for a var or nuvar during constraint gathering *)
+ | CondCons of constraint_origin * nexp_range list * nexp_range list
type t_params = (string * kind) list
type tannot = ((t_params * t) * tag * nexp_range list * effect) option
@@ -104,7 +104,7 @@ let get_index n =
| _ -> assert false
let get_c_loc = function
- | Patt l | Expr l | Abre l | Specc l -> l
+ | Patt l | Expr l | Specc l -> l
let rec string_of_list sep string_of = function
| [] -> ""
@@ -675,8 +675,8 @@ let rec cs_subst t_env cs =
| LtEq(l,n1,n2)::cs -> LtEq(l,n_subst t_env n1, n_subst t_env n2)::(cs_subst t_env cs)
| In(l,s,ns)::cs -> InS(l,n_subst t_env {nexp=Nvar s},ns)::(cs_subst t_env cs)
| InS(l,n,ns)::cs -> InS(l,n_subst t_env n,ns)::(cs_subst t_env cs)
- | InOpen(l,n,ns)::cs -> InOpen(l,n_subst t_env n,ns)::(cs_subst t_env cs)
-
+ | CondCons(l, pats, exps)::cs -> CondCons(l, cs_subst t_env pats, cs_subst t_env exps)::(cs_subst t_env cs)
+
let subst k_env t cs e =
let subst_env = Envmap.from_list
(List.map (fun (id,k) -> (id,
@@ -1076,9 +1076,12 @@ let rec simple_constraint_check in_env cs =
then begin resolve_nsubst n1; resolve_nsubst n2; equate_n n1' n2'; None end
else Some(Eq(co,n1',n2'))
| _,_ -> Some(Eq(co,n1',n2'))) in
- (match check_eq true n1 n2 with
- | None -> (check cs)
- | Some(c) -> c::(check cs))
+ (match contains_in_vars in_env n1, contains_in_vars in_env n2 with
+ | None,None ->
+ (match check_eq true n1 n2 with
+ | None -> (check cs)
+ | Some(c) -> c::(check cs))
+ | _ -> (Eq(co,n1,n2)::(check cs)))
| GtEq(co,n1,n2)::cs ->
(* let _ = Printf.printf ">= check, about to eval_nexp of %s, %s\n" (n_to_string n1) (n_to_string n2) in *)
let n1',n2' = eval_nexp n1,eval_nexp n2 in
diff --git a/src/type_internal.mli b/src/type_internal.mli
index 07b0e746..04c5bf9c 100644
--- a/src/type_internal.mli
+++ b/src/type_internal.mli
@@ -65,7 +65,7 @@ type tag =
type constraint_origin =
| Patt of Parse_ast.l
| Expr of Parse_ast.l
- | Abre of Parse_ast.l
+ | Fun of Parse_ast.l
| Specc of Parse_ast.l
(* Constraints for nexps, plus the location which added the constraint *)
@@ -75,7 +75,7 @@ type nexp_range =
| GtEq of constraint_origin * nexp * nexp
| In of constraint_origin * string * int list
| InS of constraint_origin * nexp * int list (* This holds the given value for string after a substitution *)
- | InOpen of constraint_origin * nexp * int list (* This holds a non-exhaustive value/s for a var or nuvar during constraint gathering *)
+ | CondCons of constraint_origin * nexp_range list * nexp_range list (* Constraints from one path from a conditional (pattern or if) and the constraints from that conditional *)
val get_c_loc : constraint_origin -> Parse_ast.l