summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKathy Gray2016-01-19 18:01:15 +0000
committerKathy Gray2016-01-19 18:01:25 +0000
commitee4e2fdcc589406411ef17509e8140f21aee5c02 (patch)
tree273be501d592c34b1559927e0c373559c365ac78 /src
parentee6626ac028699d069c5b7492e77448479e7c68f (diff)
Put None and Some into interpreter environments
Also making progress towards separating int sized things from integer sized things
Diffstat (limited to 'src')
-rw-r--r--src/lem_interp/interp.lem5
-rw-r--r--src/spec_analysis.ml6
-rw-r--r--src/type_internal.ml345
-rw-r--r--src/type_internal.mli17
4 files changed, 288 insertions, 85 deletions
diff --git a/src/lem_interp/interp.lem b/src/lem_interp/interp.lem
index 4f00f84b..bf82010e 100644
--- a/src/lem_interp/interp.lem
+++ b/src/lem_interp/interp.lem
@@ -325,7 +325,10 @@ let rec to_aliases (Defs defs) =
val to_data_constructors : defs tannot -> map string typ
let rec to_data_constructors (Defs defs) =
match defs with
- | [] -> Map.empty
+ | [] ->
+ (*Prime environment with built-in constructors*)
+ Map.insert "Some" (Typ_aux (Typ_var (Kid_aux (Var "a") Unknown)) Unknown)
+ (Map.insert "None" unit_t Map.empty)
| def :: defs ->
match def with
| DEF_type (TD_aux t _)->
diff --git a/src/spec_analysis.ml b/src/spec_analysis.ml
index 62b13d95..0c751c9b 100644
--- a/src/spec_analysis.ml
+++ b/src/spec_analysis.ml
@@ -66,6 +66,12 @@ let rec power_big_int b n =
then unit_big_int
else mult_big_int b (power_big_int b (sub_big_int n unit_big_int))
+let unpower_of_2 b =
+ let two = big_int_of_int 2 in
+ let four = big_int_of_int 4 in
+ let eight = big_int_of_int 8 in
+ ()
+
let is_within_range candidate range constraints =
match candidate.t with
| Tapp("atom", [TA_nexp n]) ->
diff --git a/src/type_internal.ml b/src/type_internal.ml
index 9d43d99c..27d6a1bb 100644
--- a/src/type_internal.ml
+++ b/src/type_internal.ml
@@ -982,6 +982,158 @@ let nexp_eq n1 n2 =
(* let _ = Printf.eprintf "compared nexps %s\n" (string_of_bool b) in*)
b
+
+(*determine if ne is divisble without remainder by n,
+ for now considering easily checked divisibility:
+ i.e. if ne is 2^n, where we otherwhere assume n>0 we just check for 2,
+ not for numbers 2^m where n >= m
+*)
+let divisible_by ne n =
+ let num,var,uvar,immediate_answer = match n.nexp with
+ | Nconst i | N2n(_,Some i)->
+ if eq_big_int i unit_big_int || eq_big_int i (minus_big_int unit_big_int)
+ then None,None,None,Some true
+ else Some i,None,None,None
+ | Nvar v -> None, Some(v), None, None
+ | Nuvar _ -> None, None, Some(get_index n), None
+ | _ -> None, None, None, Some(false)
+ in
+ match immediate_answer with
+ | Some answer -> answer
+ | None ->
+ let rec walk_nexp n = match n.nexp with
+ | Npos_inf | Nneg_inf -> true
+ | Ninexact -> false
+ | Nvar v ->
+ (match var with
+ | Some v' -> v = v'
+ | _ -> false)
+ | Nuvar _ ->
+ (match uvar with
+ | Some n' -> (get_index n) = n'
+ | _ -> false)
+ | Nconst i | N2n(_,Some i) ->
+ (match num with
+ | Some i' -> eq_big_int (mod_big_int i i') zero_big_int
+ | _ -> false)
+ | N2n(n,_) ->
+ (match num with
+ | Some i -> eq_big_int i (big_int_of_int 2)
+ | _ -> false)
+ | Npow(n,_) | Nneg n -> walk_nexp n
+ | Nmult(n1,n2) -> walk_nexp n1 || walk_nexp n2
+ | Nadd(n1,n2) | Nsub(n1,n2) -> walk_nexp n1 && walk_nexp n2
+ in walk_nexp ne
+
+(*divide ne by n, only gives correct answer when divisible_by is true*)
+let divide_by ne n =
+ let num,var,uvar,immediate_answer = match n.nexp with
+ | Nconst i | N2n(_,Some i)->
+ if eq_big_int i unit_big_int
+ then None,None,None,Some n
+ else if eq_big_int i (minus_big_int unit_big_int)
+ then None,None,None,Some (mk_neg n)
+ else Some i,None,None,None
+ | Nvar v -> None, Some(v), None, None
+ | Nuvar _ -> None, None, Some(get_index n), None
+ | _ -> None, None, None, Some n
+ in
+ match immediate_answer with
+ | Some answer -> answer
+ | None ->
+ let rec walk_nexp n = match n.nexp with
+ | Npos_inf ->
+ (match num with
+ | Some(i) -> if lt_big_int i zero_big_int then mk_n_inf() else n
+ | _ -> n)
+ | Nneg_inf ->
+ (match num with
+ | Some(i) -> if lt_big_int i zero_big_int then mk_p_inf() else n
+ | _ -> n)
+ | Ninexact -> n
+ | Nvar v ->
+ (match var with
+ | Some v' -> if v = v' then n_one else n
+ | _ -> n)
+ | Nuvar _ ->
+ (match uvar with
+ | Some n' -> if (get_index n) = n' then n_one else n
+ | _ -> n)
+ | Nconst i | N2n(_,Some i) ->
+ (match num with
+ | Some i' -> mk_c (div_big_int i i')
+ | _ -> n)
+ | N2n(n1,_) ->
+ (match num with
+ | Some i -> if eq_big_int i (big_int_of_int 2) then mk_2n (mk_sub n1 n_one) else n
+ | _ -> n)
+ | Npow(nv,i) ->
+ (match nv.nexp,var,uvar with
+ | Nvar v, Some v', None -> if v = v' then mk_pow nv (i-1) else n
+ | Nuvar _,None, Some i -> if (get_index nv) = i then mk_pow nv (i-1) else n
+ | _ -> n)
+ | Nneg n -> mk_neg (walk_nexp n)
+ | Nmult(n1,n2) -> mk_mult (walk_nexp n1) (walk_nexp n2)
+ | Nadd(n1,n2) -> mk_add (walk_nexp n1) (walk_nexp n2)
+ | Nsub(n1,n2) -> mk_sub (walk_nexp n1) (walk_nexp n2)
+ in walk_nexp ne
+
+(*Remove nv (assumed to be either a nuvar or an nvar) from ne as much as possible.
+ Due to requiring integral values only, as well as variables multiplied by others,
+ there might be some non-removable factors
+ Returns the variable with any non-removable factors, and the rest of the expression
+*)
+let isolate_nexp nv ne =
+ let normal_ne = normalize_nexp ne in
+ let var,uvar = match nv.nexp with
+ | Nvar v -> Some v, None
+ | Nuvar _ -> None, Some (get_index nv)
+ | _ -> None, None in
+ let rec remove_from ne = match ne.nexp with
+ | Npos_inf | Nneg_inf | Ninexact | Nconst _ | N2n(_,Some _)-> ne,None
+ | Nvar v ->
+ (match var with
+ | Some v' -> if v = v' then (n_zero,Some ne) else (ne,None)
+ | _ -> (ne,None))
+ | Nuvar _ ->
+ (match uvar with
+ | Some n' -> if (get_index ne) = n' then n_zero,Some ne else ne,None
+ | _ -> ne,None)
+ | N2n(n1,_) | Npow(n1,_)->
+ (match remove_from n1 with
+ | (_, None) -> ne,None
+ | (_,Some _) -> (n_zero,Some ne))
+ | Nneg n -> assert false (*Normal forms shouldn't have nneg*)
+ | Nmult(n1,n2) ->
+ (match (remove_from n1, remove_from n2) with
+ | (_, None),(_,None) -> (ne,None)
+ | _ -> (n_zero, Some ne))
+ | Nadd(n1,n2) ->
+ (match (remove_from n1, remove_from n2) with
+ | (_,None),(_,None) -> ne,None
+ | (new_n1,Some nv),(_,None) -> (mk_add new_n1 n2, Some nv)
+ | (_, None),(new_n2,Some nv) -> (mk_add n1 new_n2, Some nv)
+ | (_, Some _), (_, Some _) -> (n_zero, Some ne) (*It's all gone horribly wrong, punt*))
+ | Nsub(n1,n2) -> assert false in (*Normal forms shouldn't have nsub*)
+ let (new_ne,new_nv) = remove_from normal_ne in
+ let new_ne = normalize_nexp new_ne in
+ match new_nv with
+ | None -> assert false (*Oh my*)
+ | Some n_nv ->
+ (match n_nv.nexp with
+ | Nvar _ | Nuvar _ | N2n _ | Npow _ | Nadd _ | Nneg _ | Nsub _ -> (n_nv,new_ne)
+ | Nconst _ | Ninexact | Npos_inf | Nneg_inf -> assert false (*double oh my*)
+ | Nmult(n1,n2) ->
+ if nexp_eq n1 n_nv
+ then if divisible_by new_ne n2
+ then (n1, normalize_nexp (divide_by new_ne n2))
+ else (n_nv, new_ne)
+ else if nexp_eq n2 n_nv
+ then if divisible_by new_ne n1
+ then (n2, normalize_nexp (divide_by new_ne n1))
+ else (n_nv, new_ne)
+ else assert false (*really bad*))
+
let nexp_one_more_than n1 n2 =
let n1,n2 = (normalize_nexp (normalize_nexp n1)), (normalize_nexp (normalize_nexp n2)) in
match n1.nexp,n2.nexp with
@@ -1246,29 +1398,46 @@ let contains_nuvar_nexp n ne =
| _ -> false in
search ne
-let rec contains_nuvar n cs = match cs with
+let contains_nvar_nexp n ne =
+ let compare_to v = match n.nexp with
+ | Nvar v' -> v = v'
+ | _ -> false in
+ let rec search ne =
+ match ne.nexp with
+ | Nvar v-> compare_to v
+ | Nadd(n1,n2) | Nmult(n1,n2) | Nsub(n1,n2) -> search n1 || search n2
+ | N2n(n,_) | Nneg n | Npow(n,_) -> search n
+ | _ -> false in
+ search ne
+
+let rec contains_n nexp_contains n cs =
+ let contains = contains_n nexp_contains in
+ match cs with
| [] -> []
| ((LtEq(_,_,nl,nr) | Lt(_,_,nl,nr) | GtEq(_,_,nl,nr) | Gt(_,_,nl,nr) | Eq(_,nl,nr) | NtEq(_,nl,nr)) as co)::cs ->
- if (contains_nuvar_nexp n nl || contains_nuvar_nexp n nr)
- then co::(contains_nuvar n cs)
- else contains_nuvar n cs
+ if (nexp_contains n nl || nexp_contains n nr)
+ then co::(contains n cs)
+ else contains n cs
| CondCons(so,kind,_,conds,exps)::cs ->
- let conds' = contains_nuvar n conds in
- let exps' = contains_nuvar n exps in
+ let conds' = contains n conds in
+ let exps' = contains n exps in
(match conds',exps' with
- | [],[] -> contains_nuvar n cs
- | _ -> CondCons(so,kind,None,conds',exps')::contains_nuvar n cs)
+ | [],[] -> contains n cs
+ | _ -> CondCons(so,kind,None,conds',exps')::contains n cs)
| BranchCons(so,_,b_cs)::cs ->
- (match contains_nuvar n b_cs with
- | [] -> contains_nuvar n cs
- | b -> BranchCons(so,None,b)::contains_nuvar n cs)
+ (match contains n b_cs with
+ | [] -> contains n cs
+ | b -> BranchCons(so,None,b)::contains n cs)
| (Predicate(so,cp,cn) as co)::cs ->
- (match contains_nuvar n [cp;cn] with
- | [] -> contains_nuvar n cs
- | _ -> co::contains_nuvar n cs)
- | _::cs -> contains_nuvar n cs
-
-let rec refine_guarantees max_lt min_gt id cs =
+ (match contains n [cp;cn] with
+ | [] -> contains n cs
+ | _ -> co::contains n cs)
+ | _::cs -> contains n cs
+
+let contains_nuvar = contains_n contains_nuvar_nexp
+let contains_nvar = contains_n contains_nvar_nexp
+
+let rec refine_guarantees check_nvar max_lt min_gt id cs =
match cs with
| [] ->
(match max_lt,min_gt with
@@ -1277,52 +1446,56 @@ let rec refine_guarantees max_lt min_gt id cs =
| None,Some(c,i) -> [GtEq(c,Guarantee,id,i)]
| Some(cl,il),Some(cg,ig) -> [LtEq(cl,Guarantee,id,il);GtEq(cg,Guarantee,id,ig)])
| LtEq(c,Guarantee,nes,neb)::cs ->
- (match nes.nexp,neb.nexp,max_lt with
- | Nuvar _ , Nconst i,None->
+ (match nes.nexp,neb.nexp,check_nvar,max_lt with
+ | Nuvar _ , Nconst i,false,None | Nvar _ , Nconst i, true, None ->
if nexp_eq id nes
- then refine_guarantees (Some(c,neb)) min_gt id cs (*new max*)
- else refine_guarantees max_lt min_gt id cs
- | Nuvar _ , Nconst i, Some(cm, {nexp = Nconst im}) ->
+ then refine_guarantees check_nvar (Some(c,neb)) min_gt id cs (*new max*)
+ else refine_guarantees check_nvar max_lt min_gt id cs
+ | Nuvar _ , Nconst i, false,Some(cm, {nexp = Nconst im})
+ | Nvar _ , Nconst i, true,Some(cm, {nexp = Nconst im}) ->
if nexp_eq id nes && i >= im
- then refine_guarantees (Some(c,neb)) min_gt id cs (*replace old max*)
- else refine_guarantees max_lt min_gt id cs
- | _ -> refine_guarantees max_lt min_gt id cs)
+ then refine_guarantees check_nvar (Some(c,neb)) min_gt id cs (*replace old max*)
+ else refine_guarantees check_nvar max_lt min_gt id cs
+ | _ -> refine_guarantees check_nvar max_lt min_gt id cs)
| Lt(c,Guarantee,nes,neb)::cs ->
- (match nes.nexp,neb.nexp,max_lt with
- | Nuvar _ , Nconst i,None->
+ (match nes.nexp,neb.nexp,check_nvar,max_lt with
+ | Nuvar _ , Nconst i,false,None | Nvar _ , Nconst i,true,None->
if nexp_eq id nes
- then refine_guarantees (Some(c,neb)) min_gt id cs (*new max*)
- else refine_guarantees max_lt min_gt id cs
- | Nuvar _ , Nconst i, Some(cm, {nexp = Nconst im}) ->
+ then refine_guarantees check_nvar (Some(c,neb)) min_gt id cs (*new max*)
+ else refine_guarantees check_nvar max_lt min_gt id cs
+ | Nuvar _ , Nconst i,false, Some(cm, {nexp = Nconst im})
+ | Nvar _ , Nconst i,true, Some(cm, {nexp = Nconst im}) ->
if nexp_eq id nes && i > im
- then refine_guarantees (Some(c,neb)) min_gt id cs (*replace old max*)
- else refine_guarantees max_lt min_gt id cs
- | _ -> refine_guarantees max_lt min_gt id cs)
+ then refine_guarantees check_nvar (Some(c,neb)) min_gt id cs (*replace old max*)
+ else refine_guarantees check_nvar max_lt min_gt id cs
+ | _ -> refine_guarantees check_nvar max_lt min_gt id cs)
| GtEq(c,Guarantee,nes,neb)::cs ->
- (match nes.nexp,neb.nexp,min_gt with
- | Nuvar _ , Nconst i,None->
+ (match nes.nexp,neb.nexp,check_nvar,min_gt with
+ | Nuvar _ , Nconst i,false,None | Nvar _ , Nconst i,true,None->
if nexp_eq id nes
- then refine_guarantees max_lt (Some(c,neb)) id cs (*new min*)
- else refine_guarantees max_lt min_gt id cs
- | Nuvar _ , Nconst i, Some(cm, {nexp = Nconst im}) ->
+ then refine_guarantees check_nvar max_lt (Some(c,neb)) id cs (*new min*)
+ else refine_guarantees check_nvar max_lt min_gt id cs
+ | Nuvar _ , Nconst i,false, Some(cm, {nexp = Nconst im})
+ | Nvar _ , Nconst i,true, Some(cm, {nexp = Nconst im}) ->
if nexp_eq id nes && i <= im
- then refine_guarantees max_lt (Some(c,neb)) id cs (*replace old min*)
- else refine_guarantees max_lt min_gt id cs
- | _ -> refine_guarantees max_lt min_gt id cs)
+ then refine_guarantees check_nvar max_lt (Some(c,neb)) id cs (*replace old min*)
+ else refine_guarantees check_nvar max_lt min_gt id cs
+ | _ -> refine_guarantees check_nvar max_lt min_gt id cs)
| Gt(c,Guarantee,nes,neb)::cs ->
- (match nes.nexp,neb.nexp,min_gt with
- | Nuvar _ , Nconst i,None->
+ (match nes.nexp,neb.nexp,check_nvar,min_gt with
+ | Nuvar _ , Nconst i,false,None | Nvar _ , Nconst i,true,None->
if nexp_eq id nes
- then refine_guarantees max_lt (Some(c,neb)) id cs (*new min*)
- else refine_guarantees max_lt min_gt id cs
- | Nuvar _ , Nconst i, Some(cm, {nexp = Nconst im}) ->
+ then refine_guarantees check_nvar max_lt (Some(c,neb)) id cs (*new min*)
+ else refine_guarantees check_nvar max_lt min_gt id cs
+ | Nuvar _ , Nconst i, false, Some(cm, {nexp = Nconst im})
+ | Nvar _ , Nconst i, true, Some(cm, {nexp = Nconst im}) ->
if nexp_eq id nes && i < im
- then refine_guarantees max_lt (Some(c,neb)) id cs (*replace old min*)
- else refine_guarantees max_lt min_gt id cs
- | _ -> refine_guarantees max_lt min_gt id cs)
- | c::cs -> c::(refine_guarantees max_lt min_gt id cs)
+ then refine_guarantees check_nvar max_lt (Some(c,neb)) id cs (*replace old min*)
+ else refine_guarantees check_nvar max_lt min_gt id cs
+ | _ -> refine_guarantees check_nvar max_lt min_gt id cs)
+ | c::cs -> c::(refine_guarantees check_nvar max_lt min_gt id cs)
-let rec refine_requires min_lt max_gt id cs =
+let rec refine_requires check_nvar min_lt max_gt id cs =
match cs with
| [] ->
(match min_lt,max_gt with
@@ -1331,50 +1504,54 @@ let rec refine_requires min_lt max_gt id cs =
| None,Some(c,i) -> [GtEq(c,Require,id,i)]
| Some(cl,il),Some(cg,ig) -> [LtEq(cl,Require,id,il);GtEq(cg,Require,id,ig)])
| LtEq(c,Require,nes,neb)::cs ->
- (match nes.nexp,neb.nexp,min_lt with
- | Nuvar _ , Nconst i,None->
+ (match nes.nexp,neb.nexp,check_nvar,min_lt with
+ | Nuvar _ , Nconst i,false,None | Nvar _ , Nconst i,true,None ->
if nexp_eq id nes
- then refine_requires(Some(c,neb)) max_gt id cs (*new min*)
- else refine_requires min_lt max_gt id cs
- | Nuvar _ , Nconst i, Some(cm, {nexp = Nconst im}) ->
+ then refine_requires check_nvar (Some(c,neb)) max_gt id cs (*new min*)
+ else refine_requires check_nvar min_lt max_gt id cs
+ | Nuvar _ , Nconst i, false, Some(cm, {nexp = Nconst im})
+ | Nvar _ , Nconst i, true, Some(cm, {nexp = Nconst im}) ->
if nexp_eq id nes && i <= im
- then refine_requires (Some(c,neb)) max_gt id cs (*replace old min*)
- else refine_requires min_lt max_gt id cs
- | _ -> refine_guarantees min_lt max_gt id cs)
+ then refine_requires check_nvar (Some(c,neb)) max_gt id cs (*replace old min*)
+ else refine_requires check_nvar min_lt max_gt id cs
+ | _ -> refine_guarantees check_nvar min_lt max_gt id cs)
| Lt(c,Require,nes,neb)::cs ->
- (match nes.nexp,neb.nexp,min_lt with
- | Nuvar _ , Nconst i,None->
+ (match nes.nexp,neb.nexp,check_nvar,min_lt with
+ | Nuvar _ , Nconst i,false,None | Nvar _ , Nconst i,true,None->
if nexp_eq id nes
- then refine_requires(Some(c,neb)) max_gt id cs (*new min*)
- else refine_requires min_lt max_gt id cs
- | Nuvar _ , Nconst i, Some(cm, {nexp = Nconst im}) ->
+ then refine_requires check_nvar(Some(c,neb)) max_gt id cs (*new min*)
+ else refine_requires check_nvar min_lt max_gt id cs
+ | Nuvar _ , Nconst i, false, Some(cm, {nexp = Nconst im})
+ | Nvar _ , Nconst i, true, Some(cm, {nexp = Nconst im}) ->
if nexp_eq id nes && i < im
- then refine_requires (Some(c,neb)) max_gt id cs (*replace old min*)
- else refine_requires min_lt max_gt id cs
- | _ -> refine_guarantees min_lt max_gt id cs)
+ then refine_requires check_nvar (Some(c,neb)) max_gt id cs (*replace old min*)
+ else refine_requires check_nvar min_lt max_gt id cs
+ | _ -> refine_guarantees check_nvar min_lt max_gt id cs)
| GtEq(c,Require,nes,neb)::cs ->
- (match nes.nexp,neb.nexp,max_gt with
- | Nuvar _ , Nconst i,None->
+ (match nes.nexp,neb.nexp,check_nvar,max_gt with
+ | Nuvar _ , Nconst i,false,None | Nvar _ , Nconst i,true,None ->
if nexp_eq id nes
- then refine_requires min_lt (Some(c,neb)) id cs (*new max*)
- else refine_requires min_lt max_gt id cs
- | Nuvar _ , Nconst i, Some(cm, {nexp = Nconst im}) ->
+ then refine_requires check_nvar min_lt (Some(c,neb)) id cs (*new max*)
+ else refine_requires check_nvar min_lt max_gt id cs
+ | Nuvar _ , Nconst i, false, Some(cm, {nexp = Nconst im})
+ | Nvar _ , Nconst i, true, Some(cm, {nexp = Nconst im}) ->
if nexp_eq id nes && i >= im
- then refine_requires min_lt (Some(c,neb)) id cs (*replace old max*)
- else refine_requires min_lt max_gt id cs
- | _ -> refine_requires min_lt max_gt id cs)
+ then refine_requires check_nvar min_lt (Some(c,neb)) id cs (*replace old max*)
+ else refine_requires check_nvar min_lt max_gt id cs
+ | _ -> refine_requires check_nvar min_lt max_gt id cs)
| Gt(c,Require,nes,neb)::cs ->
- (match nes.nexp,neb.nexp,max_gt with
- | Nuvar _ , Nconst i,None->
+ (match nes.nexp,neb.nexp,check_nvar,max_gt with
+ | Nuvar _ , Nconst i,true,None | Nvar _ , Nconst i,false,None->
if nexp_eq id nes
- then refine_requires min_lt (Some(c,neb)) id cs (*new max*)
- else refine_requires min_lt max_gt id cs
- | Nuvar _ , Nconst i, Some(cm, {nexp = Nconst im}) ->
+ then refine_requires check_nvar min_lt (Some(c,neb)) id cs (*new max*)
+ else refine_requires check_nvar min_lt max_gt id cs
+ | Nuvar _ , Nconst i, false, Some(cm, {nexp = Nconst im})
+ | Nvar _ , Nconst i, true, Some(cm, {nexp = Nconst im}) ->
if nexp_eq id nes && i > im
- then refine_requires min_lt (Some(c,neb)) id cs (*replace old max*)
- else refine_requires min_lt max_gt id cs
- | _ -> refine_requires min_lt max_gt id cs)
- | c::cs -> c::(refine_requires min_lt max_gt id cs)
+ then refine_requires check_nvar min_lt (Some(c,neb)) id cs (*replace old max*)
+ else refine_requires check_nvar min_lt max_gt id cs
+ | _ -> refine_requires check_nvar min_lt max_gt id cs)
+ | c::cs -> c::(refine_requires check_nvar min_lt max_gt id cs)
let nat_t = {t = Tapp("range",[TA_nexp n_zero;TA_nexp (mk_p_inf());])}
let int_t = {t = Tapp("range",[TA_nexp (mk_n_inf());TA_nexp (mk_p_inf());])}
diff --git a/src/type_internal.mli b/src/type_internal.mli
index 23324ab5..c45f5342 100644
--- a/src/type_internal.mli
+++ b/src/type_internal.mli
@@ -283,6 +283,23 @@ val nexp_eq_check : nexp -> nexp -> bool (*structural equality only*)
val nexp_eq : nexp -> nexp -> bool
val nexp_one_more_than : nexp -> nexp -> bool
+(*Selects the subset of given list where an nexp_range contains the given nexp, presumed to be an nvar*)
+val contains_nvar : nexp -> nexp_range list -> nexp_range list
+(*As above but with nuvars*)
+val contains_nuvar : nexp -> nexp_range list -> nexp_range list
+(*Removes first nexp from second nexp, when first nexp is a nuvar or nvar.
+If it isn't possible to remove the first nexp fully and leave integral values on the resulting nexp
+(i.e. if we have isolate_nexp 'i (8*i) + 3), then we return the nexp and any non-removable factors
+(this may include 2 ^^ 'x)
+*)
+val isolate_nexp : nexp -> nexp -> (nexp * nexp)
+val refine_requires: bool -> (constraint_origin * nexp) option -> (constraint_origin * nexp) option -> Nexpmap.k -> nexp_range list -> nexp_range list
+val refine_guarantees: bool -> (constraint_origin * nexp) option -> (constraint_origin * nexp) option -> Nexpmap.k -> nexp_range list -> nexp_range list
+
+
+
+(*type relations*)
+
val conforms_to_t : def_envs -> bool -> bool -> t -> t -> bool
(* type_consistent is similar to a standard type equality, except in the case of [[consistent t1 t2]] where