summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKathy Gray2014-01-07 15:35:41 +0000
committerKathy Gray2014-01-07 15:35:41 +0000
commitaedfbef5ccfe39e661cc309d2ee1c96a5f70dc5a (patch)
tree0802f8fa5420f2d4f1930cd18e392212b4f22a80
parent093550b39e7331179cbdae913021be27f11e4153 (diff)
lem homs and type headers
-rw-r--r--language/l2.lem38
-rw-r--r--language/l2.ml88
-rw-r--r--language/l2.ott51
-rw-r--r--language/l2_rules.ott467
-rw-r--r--src/type_internal.ml3
-rw-r--r--src/type_internal.mli6
6 files changed, 385 insertions, 268 deletions
diff --git a/language/l2.lem b/language/l2.lem
index f3840866..c8eacad3 100644
--- a/language/l2.lem
+++ b/language/l2.lem
@@ -3,6 +3,7 @@ open import Pervasives
open import Map
open import Maybe
+open import Set_extra
type l =
| Unknown
@@ -11,8 +12,6 @@ type l =
val duplicates : forall 'a. list 'a -> list 'a
-val union_map : forall 'a 'b. map 'a 'b -> map 'a 'b -> map 'a 'b
-
val set_from_list : forall 'a. list 'a -> set 'a
val subst : forall 'a. list 'a -> list 'a -> bool
@@ -32,7 +31,7 @@ type base_kind = (* base kind *)
| BK_effect (* kind of effect sets *)
-type nexp = (* expression of kind $Nat$, for vector sizes and origins *)
+type nexp = (* expression of kind Nat, for vector sizes and origins *)
| Nexp_var of kid (* variable *)
| Nexp_constant of nat (* constant *)
| Nexp_times of nexp * nexp (* product *)
@@ -54,25 +53,13 @@ type base_effect = (* effect *)
| BE_nondet (* nondeterminism from intra-instruction parallelism *)
-type n_constraint = (* constraint over kind $Nat$ *)
- | NC_fixed of nexp * nexp
- | NC_bounded_ge of nexp * nexp
- | NC_bounded_le of nexp * nexp
- | NC_nat_set_bounded of kid * list nat
-
-
-type kinded_id = (* optionally kind-annotated identifier *)
- | KOpt_none of kid (* identifier *)
- | KOpt_kind of kind * kid (* kind-annotated variable *)
-
-
-type order = (* vector order specifications, of kind $Order$ *)
+type order = (* vector order specifications, of kind Order *)
| Ord_var of kid (* variable *)
| Ord_inc (* increasing (little-endian) *)
| Ord_dec (* decreasing (big-endian) *)
-type effect = (* effect set, of kind $Effects$ *)
+type effect = (* effect set, of kind Effects *)
| Effect_var of kid
| Effect_set of list base_effect (* effect set *)
@@ -81,6 +68,23 @@ type id = (* Identifier *)
| Id of x
| DeIid of x (* remove infix status *)
+let effect_union e1 e2 =
+ match (e1,e2) with
+ | (Effect_set els,Effect_set els2) -> Effect_set (els++els2)
+ end
+
+
+type n_constraint = (* constraint over kind $Nat$ *)
+ | NC_fixed of nexp * nexp
+ | NC_bounded_ge of nexp * nexp
+ | NC_bounded_le of nexp * nexp
+ | NC_nat_set_bounded of kid * list nat
+
+
+type kinded_id = (* optionally kind-annotated identifier *)
+ | KOpt_none of kid (* identifier *)
+ | KOpt_kind of kind * kid (* kind-annotated variable *)
+
type quant_item = (* Either a kinded identifier or a nexp constraint for a typquant *)
| QI_id of kinded_id (* An optionally kinded identifier *)
diff --git a/language/l2.ml b/language/l2.ml
index 1ee2b64e..02b5276a 100644
--- a/language/l2.ml
+++ b/language/l2.ml
@@ -40,7 +40,7 @@ kind_aux = (* kinds *)
type
-nexp_aux = (* expression of kind $_$, for vector sizes and origins *)
+nexp_aux = (* expression of kind Nat, for vector sizes and origins *)
Nexp_var of kid (* variable *)
| Nexp_constant of int (* constant *)
| Nexp_times of nexp * nexp (* product *)
@@ -57,30 +57,6 @@ kind =
type
-n_constraint_aux = (* constraint over kind $_$ *)
- NC_fixed of nexp * nexp
- | NC_bounded_ge of nexp * nexp
- | NC_bounded_le of nexp * nexp
- | NC_nat_set_bounded of kid * (int) list
-
-
-type
-kinded_id_aux = (* optionally kind-annotated identifier *)
- KOpt_none of kid (* identifier *)
- | KOpt_kind of kind * kid (* kind-annotated variable *)
-
-
-type
-n_constraint =
- NC_aux of n_constraint_aux * l
-
-
-type
-kinded_id =
- KOpt_aux of kinded_id_aux * l
-
-
-type
base_effect_aux = (* effect *)
BE_rreg (* read register *)
| BE_wreg (* write register *)
@@ -92,29 +68,18 @@ base_effect_aux = (* effect *)
type
-quant_item_aux = (* Either a kinded identifier or a nexp constraint for a typquant *)
- QI_id of kinded_id (* An optionally kinded identifier *)
- | QI_const of n_constraint (* A constraint for this type *)
-
-
-type
base_effect =
BE_aux of base_effect_aux * l
type
-quant_item =
- QI_aux of quant_item_aux * l
-
-
-type
-effect_aux = (* effect set, of kind $_$ *)
+effect_aux = (* effect set, of kind Effects *)
Effect_var of kid
| Effect_set of (base_effect) list (* effect set *)
type
-order_aux = (* vector order specifications, of kind $_$ *)
+order_aux = (* vector order specifications, of kind Order *)
Ord_var of kid (* variable *)
| Ord_inc (* increasing (little-endian) *)
| Ord_dec (* decreasing (big-endian) *)
@@ -127,12 +92,6 @@ id_aux = (* Identifier *)
type
-typquant_aux = (* type quantifiers and constraints *)
- TypQ_tq of (quant_item) list
- | TypQ_no_forall (* sugar, omitting quantifier and constraints *)
-
-
-type
effect =
Effect_aux of effect_aux * l
@@ -148,6 +107,47 @@ id =
type
+n_constraint_aux = (* constraint over kind $_$ *)
+ NC_fixed of nexp * nexp
+ | NC_bounded_ge of nexp * nexp
+ | NC_bounded_le of nexp * nexp
+ | NC_nat_set_bounded of kid * (int) list
+
+
+type
+kinded_id_aux = (* optionally kind-annotated identifier *)
+ KOpt_none of kid (* identifier *)
+ | KOpt_kind of kind * kid (* kind-annotated variable *)
+
+
+type
+n_constraint =
+ NC_aux of n_constraint_aux * l
+
+
+type
+kinded_id =
+ KOpt_aux of kinded_id_aux * l
+
+
+type
+quant_item_aux = (* Either a kinded identifier or a nexp constraint for a typquant *)
+ QI_id of kinded_id (* An optionally kinded identifier *)
+ | QI_const of n_constraint (* A constraint for this type *)
+
+
+type
+quant_item =
+ QI_aux of quant_item_aux * l
+
+
+type
+typquant_aux = (* type quantifiers and constraints *)
+ TypQ_tq of (quant_item) list
+ | TypQ_no_forall (* sugar, omitting quantifier and constraints *)
+
+
+type
lit_aux = (* Literal constant *)
L_unit (* $() : _$ *)
| L_zero (* $_ : _$ *)
diff --git a/language/l2.ott b/language/l2.ott
index e238fef6..2224eb32 100644
--- a/language/l2.ott
+++ b/language/l2.ott
@@ -2,7 +2,7 @@ indexvar n , m , i , j ::=
{{ phantom }}
{{ com Index variables for meta-lists }}
-metavar num , zero ::=
+metavar num ::=
{{ phantom }}
{{ lex numeric }}
{{ ocaml int }}
@@ -53,6 +53,7 @@ embed
{{ lem
open import Map
open import Maybe
+open import Set_extra
type l =
| Unknown
@@ -61,8 +62,6 @@ type l =
val duplicates : forall 'a. list 'a -> list 'a
-val union_map : forall 'a 'b. map 'a 'b -> map 'a 'b -> map 'a 'b
-
val set_from_list : forall 'a. list 'a -> set 'a
val subst : forall 'a. list 'a -> list 'a -> bool
@@ -111,18 +110,18 @@ id :: '' ::=
{{ aux _ l }}
| x :: :: id
| ( deinfix x ) :: :: deIid {{ com remove infix status }}
- | bool :: M :: bool {{ com Built in type identifiers }} {{ ichlo bool_id }}
- | bit :: M :: bit {{ ichlo bit_id }}
- | unit :: M :: unit {{ ichlo unit_id }}
- | nat :: M :: nat {{ ichlo nat_id }}
- | string :: M :: string {{ tex \ottkw{string} }} {{ ichlo string_id }}
- | enum :: M :: enum {{ ichlo enum_id }}
- | vector :: M :: vector {{ ichlo vector_id }}
- | list :: M :: list {{ ichlo list_id }}
- | set :: M :: set {{ ichlo set_id }}
- | reg :: M :: reg {{ ichlo reg_id }}
- | to_num :: M :: tonum {{ com Built in function identifiers }} {{ ichlo to_num }}
- | to_vec :: M :: tovec {{ ichlo to_vec }}
+ | bool :: M :: bool {{ com Built in type identifiers }} {{ ichlo (Id "bool") }}
+ | bit :: M :: bit {{ ichlo (Id "bit") }}
+ | unit :: M :: unit {{ ichlo (Id "unit") }}
+ | nat :: M :: nat {{ ichlo (Id "nat") }}
+ | string :: M :: string {{ tex \ottkw{string} }} {{ ichlo (Id "string") }}
+ | enum :: M :: enum {{ ichlo (Id "enum") }}
+ | vector :: M :: vector {{ ichlo (Id "vector") }}
+ | list :: M :: list {{ ichlo (Id "list") }}
+ | set :: M :: set {{ ichlo (Id "set") }}
+ | reg :: M :: reg {{ ichlo (Id "reg") }}
+ | to_num :: M :: tonum {{ com Built in function identifiers }} {{ ichlo (Id "to_num") }}
+ | to_vec :: M :: tovec {{ ichlo (Id "to_vec") }}
% Note: we have just a single namespace. We don't want the same
% identifier to be reused as a type name or variable, expression
% variable, and field name. We don't enforce any lexical convention
@@ -158,7 +157,7 @@ kind :: 'K_' ::=
% we'll never use ...-> Nat , .. Order , .. or Effects
nexp :: 'Nexp_' ::=
- {{ com expression of kind $[[Nat]]$, for vector sizes and origins }}
+ {{ com expression of kind Nat, for vector sizes and origins }}
{{ aux _ l }}
| kid :: :: var {{ com variable }}
| num :: :: constant {{ com constant }}
@@ -169,7 +168,7 @@ nexp :: 'Nexp_' ::=
| ( nexp ) :: S :: paren {{ ichlo [[nexp]] }}
order :: 'Ord_' ::=
- {{ com vector order specifications, of kind $[[Order]]$}}
+ {{ com vector order specifications, of kind Order}}
{{ aux _ l }}
| kid :: :: var {{ com variable }}
| inc :: :: inc {{ com increasing (little-endian) }}
@@ -189,12 +188,24 @@ base_effect :: 'BE_' ::=
effect :: 'Effect_' ::=
- {{ com effect set, of kind $[[Effects]]$ }}
+ {{ com effect set, of kind Effects }}
{{ aux _ l }}
| kid :: :: var
| { base_effect1 , .. , base_effectn } :: :: set {{ com effect set }}
- | pure :: M :: pure {{ com sugar for empty effect set }} {{ ichlo [] }}
- | effect1 u+ .. u+ effectn :: M :: union {{ com meta operation for combining sets of effects }} {{ ichlo [] }}
+ | pure :: M :: pure {{ com sugar for empty effect set }}
+ {{ lem (Effect_set []) }} {{icho [[{}]] }}
+ | effect1 u+ .. u+ effectn :: M :: union {{ com meta operation for combining sets of effects }} {{ icho [] }}
+ {{ lem (List.foldr effect_union (Effect_set []) [[effect1..effectn]]) }}
+
+embed
+{{ lem
+let effect_union e1 e2 =
+ match (e1,e2) with
+ | (Effect_set els,Effect_set els2) -> Effect_set (els++els2)
+ end
+}}
+
+grammar
% TODO: are we going to need any effect polymorphism? Conceivably for built-in maps and folds. Yes. But we think we don't need any interesting effect-set expressions, eg effectset-variable union {rreg}.
diff --git a/language/l2_rules.ott b/language/l2_rules.ott
index 71a9b368..7e3efcb7 100644
--- a/language/l2_rules.ott
+++ b/language/l2_rules.ott
@@ -6,40 +6,26 @@
embed
{{ lem
-let blength (bit) = Ne_const 8
-let hlength (bit) = Ne_const 8
-
-%% %% let rec sumation_nes nes = match nes with
-%% %% | [ a; b] -> Ne_add a b
-%% %% | x :: y -> Ne_add x (sumation_nes y)
-%% %% end
-%% %%
-
- type definition_type =
- | DenvEmp
- | Denv of (map tid kinf) (map ... ...) (map ... ...)
-
- type env =
- | EnvEmp
- | Env of (map x v_desc) * definition_type
-
- val denv_union : definition_type -> definition_type -> definition_type
- let denv_union de1 de2 =
- match (de1,de2) with
- | (DenvEmp,de2) -> de2
- | (de1,DenvEmp) -> de1
- | ((Denv ke1 re1 ee1),(Denv ke2 re2 ee2)) ->
- Denv (union_map ke1 ke2) (union_map re1 re2) (union_map ee1 ee2)
- end
-
- val env_union : env -> env -> env
- let env_union e1 e2 =
- match (e1,e2) with
- | (EnvEmp,e2) -> e2
- | (e1,EnvEmp) -> e1
- | ((Env te1 de1),(Env te2 de2)) ->
- Env (union_map te1 te2) (denv_union de1 de2)
- end
+let rec remove_one i l =
+ match l with
+ | [] -> []
+ | i2::l2 -> if i2 = i then l2 else i2::(remove_one i l2)
+end
+
+let rec remove_from l l2 =
+ match l2 with
+ | [] -> l
+ | i::l2' -> remove_from (remove_one i l) l2'
+end
+
+let disjoint s1 s2 = Set.null (s1 inter s2)
+
+let rec disjoint_all sets =
+ match sets with
+ | [] -> true
+ | s1::[] -> true
+ | s1::s2::sets -> (disjoint s1 s2) && (disjoint_all (s2::sets))
+end
}}
@@ -81,6 +67,8 @@ ne :: 'Ne_' ::=
| ne1 + ... + nen :: :: add
| 2 ** ne :: :: exp
| ( - ne ) :: :: unary
+ | zero :: M :: zero
+ {{ lem (Ne_const 0) }}
| bitlength ( bin ) :: M :: cbin
{{ ocaml (asssert false) }}
{{ hol ARB }}
@@ -98,14 +86,14 @@ ne :: 'Ne_' ::=
{{ ocaml (assert false) }}
{{ lem (Ne_const (List.length [[exp1...expn]])) }}
- t_arg :: 't_arg_' ::= {{ phantom }}
+ t_arg :: 't_arg_' ::=
{{ com Argument to type constructors }}
| t :: :: typ
| ne :: :: nexp
| effect :: :: effect
| order :: :: order
- t_args :: '' ::= {{ phantom }}
+ t_args :: '' ::= {{ lem list t_arg }}
{{ com Arguments to type constructors }}
| t_arg1 ... t_argn :: :: T_args
@@ -125,7 +113,7 @@ S_N {{ tex {\Sigma^{\textsc{N} } } }} :: '' ::= {{ phantom }}
{{ lem [[nec1 .. necn]] }}
| S_N1 u+ .. u+ S_Nn :: M :: SN_union
{{ hol (FOLDR FUNION FEMPTY [[S_N1..S_Nn]]) }}
- {{ lem (List.fold_right union_map [[S_N1..S_Nn]] Map.empty) }}
+ {{ lem (List.foldr (++) [] [[S_N1..S_Nn]]) }}
{{ ocaml (assert false) }}
| consistent_increase ne1 ne'1 ... nen ne'n :: M :: SN_increasing
{{ com Generates constraints from pairs of constraints, where the first of each pair is always larger than the sum of the previous pair }}
@@ -136,28 +124,11 @@ S_N {{ tex {\Sigma^{\textsc{N} } } }} :: '' ::= {{ phantom }}
{{ ocaml assert false }}
{{ ichl todo }}
| resolve ( S_N ) :: :: resolution
+ {{ lem [[S_N]] (* Write constraint solver *) }}
- I :: '' ::= {{ phantom }}
- {{ com Information given by type checking an expression }}
- | < S_N , effect > :: :: I
- | Ie :: :: Iempty {{ com Empty constraints, effect }} {{ tex {\ottnt{I}_{\epsilon} } }}
- | I1 u+ .. u+ In :: :: Iunion {{ com Unions the constraints and effect }}
-
- E :: '' ::=
- {{ hol ((string,env_body) fmaptree) }}
- {{ lem env }}
- {{ com Definition environment and lexical environment }}
- | < E_t , E_d > :: :: E
- {{ hol arb }}
- {{ lem (Env [[E_t]] [[E_d]] }}
- | empty :: M :: E_empty
- {{ hol arb }}
- {{ lem EnvEmp }}
- {{ ocaml assert false }}
- | E u+ E' :: :: E_union
- {{ lem (env_union [[E]] [[E']]) }}
- E_d {{ tex {\ottnt{E}^{\textsc{d} } } }} :: 'E_d_' ::=
+ E_d {{ tex {\ottnt{E}^{\textsc{d} } } }} :: 'E_d_' ::= {{ phantom }}
+ {{ lem definition_env }}
{{ com Environments storing top level information, such as defined records, enumerations, and kinds }}
| < E_k , E_r , E_e > :: :: base
{{ hol arb }}
@@ -179,60 +150,35 @@ S_N {{ tex {\Sigma^{\textsc{N} } } }} :: '' ::= {{ phantom }}
| id :: :: id
| kid :: :: var
- E_k {{ tex \ottnt{E}^{\textsc{k} } }} :: 'E_k_' ::= {{ phantom }}
+ E_k {{ tex {\ottnt{E}^{\textsc{k} } } }} :: 'E_k_' ::= {{ phantom }}
{{ hol (tid-> kinf) }}
{{ lem (map tid kinf) }}
{{ com Kind environments }}
| { tid1 |-> kinf1 , .. , tidn |-> kinfn } :: :: concrete
{{ hol (FOLDR (\(k1,k2) E. E |+ (k1,k2)) FEMPTY [[tid1 kinf1 .. tidn kinfn]]) }}
- {{ lem (List.fold_right (fun (x,v) m -> Map.insert x v m) [[tid1 kinf1 .. tidn kinfn]] Map.empty) }}
+ {{ lem (List.foldr (fun (x,v) m -> Map.insert x v m) Map.empty [[tid1 kinf1 .. tidn kinfn]]) }}
| E_k1 u+ .. u+ E_kn :: M :: union
{{ com In a unioning kinf, {k default} u {k} results in {k} (i.e. the default is locally forgotten) }}
{{ hol (FOLDR FUNION FEMPTY [[E_k1..E_kn]]) }}
- {{ lem (List.fold_right union_map [[E_k1..E_kn]] Map.empty) }}
+ {{ lem (List.foldr (union) Map.empty [[E_k1..E_kn]]) }}
{{ ocaml (assert false) }}
| E_k u- E_k1 .. E_kn :: M :: multi_set_minus
{{ hol arb }}
- {{ lem (remove_from [[E_k]] (List.fold_right union_map [[E_k1..E_kn]] Map.empty)) }}
+ {{ lem (Map.fromList (remove_from (Set_extra.toList (Map.toSet [[E_k]]))
+ (Set_extra.toList (Map.toSet (List.foldr (union) Map.empty [[E_k1..E_kn]]))))) }}
{{ ocaml assert false }}
tinf :: 'tinf_' ::=
{{ com Type variables, type, and constraints, bound to an identifier }}
| t :: :: typ
- | E_k , S_N , tag , t :: :: quant_typ
-
- E_t {{ tex {\ottnt{E}^{\textsc{t} } } }} :: 'E_t_' ::= {{ phantom }}
- {{ hol (id |-> tinf) }}
- {{ lem map x f_desc }}
- {{ com Type environments }}
- | { id1 |-> tinf1 , .. , idn |-> tinfn } :: :: base
- {{ hol (FOLDR (\x E. E |+ x) FEMPTY [[id1 tinf1 .. idn tinfn]]) }}
- {{ lem (List.fold_right (fun (x,f) m -> Map.insert x f m) [[id1 tinf1 .. idn tinfn]] Map.empty) }}
- | ( E_t1 u+ .... u+ E_tn ) :: M :: union
- {{ hol (FOLDR FUNION FEMPTY [[E_t1....E_tn]]) }}
- {{ lem (List.fold_right union_map [[E_t1....E_tn]] Map.empty) }}
- {{ ocaml (assert false) }}
- | u+ E_t1 .. E_tn :: M :: multi_union
- {{ hol arb }}
- {{ lem (List.fold_right union_map [[E_t1..E_tn]] Map.empty) }}
- {{ ocaml assert false }}
- | E_t u- E_t1 .. E_tn :: M :: multi_set_minus
- {{ hol arb }} {{ lem (remove_from [[E_t]] (List.fold_right union_map [[E_t1..E_tn]] Map.empty)) }} {{ ocaml assert false }}
- | ( E_t1 inter .... inter E_tn ) :: M :: intersect
- {{ hol arb }}
- {{ lem (List.fold_right intersect_map [[E_t1....E_tn]] Map.empty) }}
- {{ ocaml (assert false) }}
- | inter E_t1 .. E_tn :: M :: multi_inter
- {{ hol arb }}
- {{ lem (List.fold_right intersect_map [[E_t1..E_tn]] Map.empty) }}
- {{ ocaml assert false }}
-
+ | E_k , S_N , tag , t :: :: quant_typ
field_typs :: 'FT_' ::= {{ phantom }}
{{ lem list (id * t) }}
{{ com Record fields }}
| id1 : t1 , .. , idn : tn :: :: fields
+ {{ lem [[id1 t1..idn tn]] }}
E_r {{ tex \ottnt{E}^{\textsc{r} } }} :: 'E_r_' ::= {{ phantom }}
{{ hol (id*t) |-> tinf) }}
@@ -240,28 +186,138 @@ S_N {{ tex {\Sigma^{\textsc{N} } } }} :: '' ::= {{ phantom }}
{{ com Record environments }}
| { { field_typs1 } |-> tinf1 , .. , { field_typsn } |-> tinfn } :: :: concrete
{{ hol (FOLDR (\x E. E |+ x) FEMPTY) }}
- {{ lem (List.fold_right (fun (x,f) m -> Map.insert x f m) [[field_typs1 tinf1..field_typsn tinfn]] Map.empty) }}
+ {{ lem (List.foldr (fun (x,f) m -> Map.insert x f m) Map.empty [[field_typs1 tinf1..field_typsn tinfn]]) }}
| E_r1 u+ .. u+ E_rn :: M :: union
{{ hol (FOLDR FUNION FEMPTY [[E_r1..E_rn]]) }}
- {{ lem (List.fold_right union_map [[E_r1..E_rn]] Map.empty) }}
+ {{ lem (List.foldr (union) Map.empty [[E_r1..E_rn]]) }}
{{ ocaml (assert false) }}
enumerate_map :: '' ::= {{ phantom }}
- {{ lem (list (num*id)) }}
+ {{ lem (list (nat*id)) }}
| { num1 |-> id1 ... numn |-> idn } :: :: enum_map
+ {{ lem [[num1 id1...numn idn]] }}
E_e {{ tex \ottnt{E}^{\textsc{e} } }} :: 'E_e_' ::= {{ phantom }}
- {{ lem (map t (list (num*id))) }}
+ {{ lem (map t (list (nat*id))) }}
{{ com Enumeration environments }}
| { t1 |-> enumerate_map1 , .. , tn |-> enumerate_mapn } :: :: base
- {{ lem (List.fold_right (fun (x,f) m -> Map.insert x f m) [[t1 enumerate_map1..tn enumerate_mapn]] Map.empty) }}
+ {{ lem (List.foldr (fun (x,f) m -> Map.insert x f m) Map.empty [[t1 enumerate_map1..tn enumerate_mapn]]) }}
| E_e1 u+ .. u+ E_en :: :: union
- {{ lem (List.fold_right union_map [[E_e1..E_en]] Map.empty) }}
+ {{ lem (List.foldr (union) Map.empty [[E_e1..E_en]]) }}
+
+
+embed
+{{ lem
+ type definition_env =
+ | DenvEmp
+ | Denv of (map tid kinf) * (map (list (id*t)) tinf) * (map t (list (nat*id)))
+
+}}
+
+grammar
+
+ E_t {{ tex {\ottnt{E}^{\textsc{t} } } }} :: 'E_t_' ::= {{ phantom }}
+ {{ hol (id |-> tinf) }}
+ {{ lem map id tinf }}
+ {{ com Type environments }}
+ | { id1 |-> tinf1 , .. , idn |-> tinfn } :: :: base
+ {{ hol (FOLDR (\x E. E |+ x) FEMPTY [[id1 tinf1 .. idn tinfn]]) }}
+ {{ lem (List.foldr (fun (x,f) m -> Map.insert x f m) Map.empty [[id1 tinf1 .. idn tinfn]]) }}
+ | ( E_t1 u+ .... u+ E_tn ) :: M :: union
+ {{ hol (FOLDR FUNION FEMPTY [[E_t1....E_tn]]) }}
+ {{ lem (List.foldr (union) Map.empty [[E_t1....E_tn]]) }}
+ {{ ocaml (assert false) }}
+ | u+ E_t1 .. E_tn :: M :: multi_union
+ {{ hol arb }}
+ {{ lem (List.foldr (union) Map.empty [[E_t1..E_tn]]) }}
+ {{ ocaml assert false }}
+ | E_t u- E_t1 .. E_tn :: M :: multi_set_minus
+ {{ hol arb }}
+ {{ lem (Map.fromList (remove_from (Set_extra.toList (Map.toSet [[E_t]]))
+ (Set_extra.toList (Map.toSet (List.foldr (union) Map.empty [[E_t1..E_tn]]))))) }}
+ {{ ocaml assert false }}
+ | ( E_t1 inter .... inter E_tn ) :: M :: intersect
+ {{ hol arb }}
+ {{ lem (List.foldr (fun a b -> (Map.fromList (Set_extra.toList ((Map.toSet a) inter (Map.toSet b))))) Map.empty [[E_t1....E_tn]]) }}
+ {{ ocaml (assert false) }}
+ | inter E_t1 .. E_tn :: M :: multi_inter
+ {{ hol arb }}
+ {{ lem (List.foldr (fun a b -> (Map.fromList (Set_extra.toList ((Map.toSet a) inter (Map.toSet b))))) Map.empty [[E_t1..E_tn]]) }}
+ {{ ocaml assert false }}
+
ts :: ts_ ::= {{ phantom }}
{{ lem list t }}
| t1 , .. , tn :: :: lst
+embed
+{{ lem
+let blength (bit) = Ne_const 8
+let hlength (bit) = Ne_const 8
+
+ type env =
+ | EnvEmp
+ | Env of (map id tinf) * definition_env
+
+ type inf =
+ | Iemp
+ | Inf of (list nec) * effect
+
+ val denv_union : definition_env -> definition_env -> definition_env
+ let denv_union de1 de2 =
+ match (de1,de2) with
+ | (DenvEmp,de2) -> de2
+ | (de1,DenvEmp) -> de1
+ | ((Denv ke1 re1 ee1),(Denv ke2 re2 ee2)) ->
+ Denv (ke1 union ke2) (re1 union re2) (ee1 union ee2)
+ end
+
+ val env_union : env -> env -> env
+ let env_union e1 e2 =
+ match (e1,e2) with
+ | (EnvEmp,e2) -> e2
+ | (e1,EnvEmp) -> e1
+ | ((Env te1 de1),(Env te2 de2)) ->
+ Env (te1 union te2) (denv_union de1 de2)
+ end
+
+let inf_union i1 i2 =
+ match (i1,i2) with
+ | (Iemp,i2) -> i2
+ | (i1,Iemp) -> i1
+ | (Inf n1 e1,Inf n2 e2) -> (Inf (n1++n2) (effect_union e1 e2))
+ end
+
+let fresh_kid denv = Var "x" (*TODO When strings can be manipulated, this should actually build a fresh string*)
+
+}}
+
+grammar
+
+ E :: '' ::=
+ {{ hol ((string,env_body) fmaptree) }}
+ {{ lem env }}
+ {{ com Definition environment and lexical environment }}
+ | < E_t , E_d > :: :: E
+ {{ hol arb }}
+ {{ lem (Env [[E_t]] [[E_d]]) }}
+ | empty :: M :: E_empty
+ {{ hol arb }}
+ {{ lem EnvEmp }}
+ {{ ocaml assert false }}
+ | E u+ E' :: :: E_union
+ {{ lem (env_union [[E]] [[E']]) }}
+
+ I :: '' ::= {{ lem inf }}
+ {{ com Information given by type checking an expression }}
+ | < S_N , effect > :: :: I
+ {{ lem (Inf [[S_N]] [[effect]]) }}
+ | Ie :: :: Iempty {{ com Empty constraints, effect }} {{ tex {\ottnt{I}_{\epsilon} } }}
+ {{ lem Iemp }}
+ | I1 u+ .. u+ In :: :: Iunion {{ com Unions the constraints and effect }}
+ {{ lem (List.foldr inf_union Iemp [[I1..In]]) }}
+
+
formula :: formula_ ::=
| judgement :: :: judgement
@@ -269,25 +325,30 @@ formula :: formula_ ::=
| E_k ( tid ) gives kinf :: :: lookup_k
{{ com Kind lookup }}
- {{ hol (FLOOKUP [[E_k]] [[tid]] = SOME [[k]]) }}
- {{ lem Map.lookup [[tid]] [[E_k]] = Just [[k]] }}
+ {{ hol (FLOOKUP [[E_k]] [[tid]] = SOME [[kinf]]) }}
+ {{ lem Map.lookup [[tid]] [[E_k]] = Just [[kinf]] }}
+
| E_t ( id ) gives tinf :: :: lookup_t
{{ com Type lookup }}
- {{ hol (FLOOKUP [[E_t]] [[id]] = SOME [[t]]) }}
- {{ lem Map.lookup [[id]] [[E_t]] = Just [[t]] }}
+ {{ hol (FLOOKUP [[E_t]] [[id]] = SOME [[tinf]]) }}
+ {{ lem Map.lookup [[id]] [[E_t]] = Just [[tinf]] }}
| E_k ( tid ) <-| k :: :: update_k
{{ com Update the kind associated with id to k }}
-
+ {{ lem [[true]] (*TODO: update_k needs to be rewritten*) }}
+
| E_r ( id0 .. idn ) gives t , ts :: :: lookup_r
{{ com Record lookup }}
+ {{ lem [[true]] (*TODO write a proper lookup for E_r *) }}
| E_r ( t ) gives id0 : t0 .. idn : tn :: :: lookup_rt
{{ com Record looup by type }}
+ {{ lem [[true]] (* write a proper lookup for E_r *) }}
| E_e ( t ) gives enumerate_map :: :: lookup_e
{{ com Enumeration lookup by type }}
+ {{ lem Map.lookup [[t]] [[E_e]] = Just [[enumerate_map]] }}
| dom ( E_t1 ) inter dom ( E_t2 ) = emptyset :: :: E_t_disjoint
{{ hol (DISJOINT (FDOM [[E_t1]]) (FDOM [[E_t2]])) }}
@@ -312,6 +373,7 @@ formula :: formula_ ::=
{{ lem Pervasives.not (Map.member [[id]] [[E_t]]) }}
| id0 : t0 .. idn : tn SUBSET id'0 : t'0 .. id'i : t'i :: :: subsetFields
+ {{ lem ((Set.fromList [[id0 t0..idn tn]]) subset (Set.fromList [[id'0 t'0..id'i t'i]])) }}
| num1 lt ... lt numn :: :: increasing
@@ -324,7 +386,8 @@ formula :: formula_ ::=
{{ ichl ([[E_k1]] = [[E_k2]]) }}
| E_k1 ~= E_k2 :: :: E_k_approx
- {{ ichl arb }}
+ {{ lem ([[E_k1]] = [[E_k2]]) (* Todo, not quite equality *) }}
+ {{ ich arb }}
| E_t1 = E_t2 :: :: E_t_eqn
{{ ichl ([[E_t1]] = [[E_t2]]) }}
@@ -348,20 +411,22 @@ formula :: formula_ ::=
{{ ichl ([[I1]] = [[I2]]) }}
| effect1 = effect2 :: :: Ef_eqn
- {{ ichl ([[effects1]] = [[effects2]]) }}
+ {{ ichl ([[effect1]] = [[effect2]]) }}
| t1 = t2 :: :: t_eq
{{ ichl ([[t1]] = [[t2]]) }}
| ne1 = ne2 :: :: ne_eq
{{ ichl ([[ne1]] = [[ne2]]) }}
-
+ | kid = fresh_kid ( E_d ) :: :: kid_eq
+ {{ ichl ([[kid]] = fresh_kid [[E_d]]) }}
defns
check_t :: '' ::=
defn
E_k |-t t ok :: :: check_t :: check_t_
- {{ com Well-formed types }}
+{{ lemwcf witness type check_t_witness; check check_t_w_check; }}
+{{ com Well-formed types }}
by
E_k('x) gives K_Typ
@@ -396,6 +461,7 @@ E_k |-t t ok :: :: check_t :: check_t_
defn
E_k |-e effect ok :: :: check_ef :: check_ef_
{{ com Well-formed effects }}
+{{ lemwcf witness type check_ef_witness; check check_ef_w_check; }}
by
E_k('x) gives K_Efct
@@ -413,6 +479,7 @@ E_k |-e { base_effect1 , .. , base_effectn } ok
defn
E_k |-n ne ok :: :: check_n :: check_n_
{{ com Well-formed numeric expressions }}
+{{ lemwcf witness type check_n_witness; check check_n_w_check; }}
by
E_k('x) gives K_Nat
@@ -444,6 +511,7 @@ E_k |-n 2 ** ne ok
defn
E_k |-o order ok :: :: check_ord :: check_ord_
{{ com Well-formed numeric expressions }}
+{{ lemwcf witness type check_ord_witness; check check_ord_w_check; }}
by
E_k('x) gives K_Ord
@@ -459,6 +527,7 @@ E_k |-o 'x ok
defn
E_k , k |- t_arg ok :: :: check_targs :: check_targs_
{{ com Well-formed type arguments kind check matching the application type variable }}
+{{ lemwcf witness type check_targs_witness; check check_targs_w_check; }}
by
E_k |-t t ok
@@ -487,6 +556,7 @@ teq :: '' ::=
defn
E_d |- t1 = t2 :: :: teq :: teq_
{{ com Type equality }}
+{{ lemwcf witness type check_teq_witness; check check_teq_w_check; }}
by
E_k |-t t ok
@@ -510,7 +580,7 @@ E_k(id) gives K_Abbrev u
E_d |- t1 = t3
E_d |- t2 = t4
------------------------------------------------------------ :: arrow
-E_d |- t1 -> t2 effect tag = t3 -> t4 effect tag
+E_d |- t1 -> t2 effect tag S_N = t3 -> t4 effect tag S_N
E_d |- t1 = u1 .... E_d |- tn = un
------------------------------------------------------------ :: tup
@@ -522,13 +592,24 @@ E_k(id) gives K_Lam (k1 .. kn -> K_Typ)
<E_k,E_r,E_e> |- id t_arg1 .. t_argn = id t_arg'1 .. t_arg'n
defn
-E_d , k |- t_arg = t_arg' :: :: targeq :: targeq_ by
+E_d , k |- t_arg = t_arg' :: :: targeq :: targeq_
+{{ lemwcf witness type check_targeq_witness; check check_targeq_w_check; }}
+by
+
+E_d |- t = t'
+------------------------------------------------------------ :: typ
+E_d, K_Typ |- t = t'
defns
convert_kind :: '' ::=
defn
-E_k |- kind ~> k :: :: convert_kind :: convert_kind_ by
+E_k |- kind ~> k :: :: convert_kind :: convert_kind_
+{{ lemwcf witness type convert_kind_witness; check convert_kind_w_check; }}
+by
+
+-------------------- :: Typ
+E_k |- Type ~> K_Typ
defns
convert_typ :: '' ::=
@@ -536,6 +617,7 @@ convert_typ :: '' ::=
defn
E_d |- quant_item ~> E_k1 , S_N :: :: convert_quants :: convert_quants_
{{ com Convert source quantifiers to kind environments and constraints }}
+{{ lemwcf witness type convert_quants_witness; check convert_quants_w_check; }}
by
E_k |- kind ~> k
@@ -567,6 +649,7 @@ E_d |- 'x IN {num1 , ... , numn} ~> {}, {'x IN {num1 , ..., numn}}
defn
E_d |- typschm ~> t , E_k2 , S_N :: :: convert_typschm :: convert_typschm_
{{ com Convert source types with typeschemes to internal types and kind environments }}
+{{ lemwcf witness type convert_typschm_witness; check convert_typschm_w_check; }}
by
E_d |- typ ~> t
@@ -582,6 +665,7 @@ E_d |- forall quant_item1 , ... , quant_itemn . typ ~> t, E_k, S_N1 u+ ... u+ S_
defn
E_d |- typ ~> t :: :: convert_typ :: convert_typ_
{{ com Convert source types to internal types }}
+{{ lemwcf witness type convert_typ_witness; check convert_typ_w_check; }}
by
E_k('x) gives K_Typ
@@ -614,11 +698,17 @@ E_d |- typ ~> t2
defn
E_d , k |- typ_arg ~> t_arg :: :: convert_targ :: convert_targ_
{{ com Convert source type arguments to internals }}
+{{ lemwcf witness type convert_targ_witness; check convert_targ_w_check; }}
by
+E_d |- typ ~> t
+------------------------------------- :: typ
+E_d, K_Typ |- typ ~> t
+
defn
|- nexp ~> ne :: :: convert_nexp :: convert_nexp_
{{ com Convert and normalize numeric expressions }}
+{{ lemwcf witness type convert_nexp_witness; check convert_nexp_w_check; }}
by
------------------------------------------------------------ :: var
@@ -642,7 +732,9 @@ by
|- 2** nexp ~> 2 ** ne
defn
-E_d |- exp : t :> t' , exp' , S_N :: :: coerce_typ :: coerce_typ_ by
+E_d |- exp : t :> t' , exp' , S_N :: :: coerce_typ :: coerce_typ_
+{{ lemwcf witness type coerce_typ_witness; check coerce_typ_w_check; }}
+by
E_d |- t = u
-------------------------------------- :: eq
@@ -660,16 +752,17 @@ E_e(t) gives { </numi |-> idi//i/> num |-> id </num'j |-> id'j//j/> }
------------------------------------------------ :: to_enumerate
<E_k,E_r,E_e> |- exp: enum num zero order :> t,id, {}
-E_e(t) gives { num1 |-> id1 ... numn |-> idn }
-exp' = switch exp { case id1 -> num1 ... case idn -> numn }
+E_e(t) gives { num |-> id </num''i |-> id''i//i/> num' |-> id' }
+exp' = switch exp { case id -> num </case id''i -> num''i//i/> case id' -> num' }
------------------------------------------------ :: from_enumerate
-<E_k,E_r,E_e> |- exp: t :> enum num1 numn + (- num1) inc, exp', {}
+<E_k,E_r,E_e> |- exp: t :> enum num num' + (- num) inc, exp', {}
-exp' = to_num exp
+exp' = :E_app: to_num(exp)
-------------------------------------- :: to_num
E_d |- exp: vector ne1 ne2 order :t_arg_typ: bit :> enum ne3 ne4 order,exp', { ne3 = zero, ne4 = 2** ne2}
-exp' = to_vec exp
+exp' = :E_app: to_vec(exp)
+'x = fresh_kid(E_d)
-------------------------------------- :: from_num
E_d |- exp: enum ne1 ne2 order :> vector ne3 ne4 order :t_arg_typ: bit,exp', {ne3 = zero, 'x = ne1 + ne2, ne4 = 2** 'x}
@@ -769,29 +862,29 @@ length(pat1 .. patn) = num
----------------------------------------------------------- :: vector
E |- [ pat1 , .. , patn ] : vector :t_arg_nexp: 'x num+'x inc t gives (E_t1 u+ .. u+ E_tn),S_N1 u+ .. u+ S_Nn
-E |- pat1 : t gives E_t1,S_N1 ... E |- patn : t gives E_tn,S_Nn
-disjoint doms(E_t1 , ... , E_tn)
-num1 lt ... lt numn
------------------------------------------------------------ :: indexedVectorInc
-E |- [ num1 = pat1 , ... , numn = patn ] : vector :t_arg_nexp: 'x :t_arg_nexp: 'x2 inc t gives (E_t1 u+ ... u+ E_tn), {'x<=num1, 'x2 >= numn + (- num1)} u+ S_N1 u+ ... u+ S_Nn
-
-E |- pat1 : t gives E_t1,S_N1 ... E |- patn : t gives E_tn,S_Nn
-disjoint doms(E_t1 , ... , E_tn)
-num1 gt ... gt numn
------------------------------------------------------------ :: indexedVectorDec
-E |- [ num1 = pat1 , ... , numn = patn ] : vector :t_arg_nexp: 'x :t_arg_nexp: 'x2 dec t gives (E_t1 u+ ... u+ E_tn), {'x>=num1,'x2<=num1 +(-numn)} u+ S_N1 u+ ... u+ S_Nn
-
-E |- pat1 : vector ne1 ne'1 inc t gives E_t1,S_N1 ... E |- patn : vector nen ne'n inc t gives E_tn,S_Nn
-disjoint doms(E_t1 , ... , E_tn)
-S_N0 = consistent_increase ne1 ne'1 ... nen ne'n
------------------------------------------------------------ :: vectorConcatInc
-E |- pat1 : ... : patn : vector :t_arg_nexp: 'x :t_arg_nexp: 'x2 inc t gives (E_t1 u+ ... u+ E_tn),{'x<=ne1,'x2>= ne'1 + ... + ne'n} u+ S_N0 u+ S_N1 u+ ... u+ S_Nn
-
-E |- pat1 : vector ne1 ne'1 dec t gives E_t1,S_N1 ... E |- patn : vector nen ne'n dec t gives E_tn,S_Nn
-disjoint doms(E_t1 , ... , E_tn)
-S_N0 = consistent_decrease ne1 ne'1 ... nen ne'n
------------------------------------------------------------ :: vectorConcatDec
-E |- pat1 : ... : patn : vector :t_arg_nexp: 'x :t_arg_nexp: 'x2 inc t gives (E_t1 u+ ... u+ E_tn),{'x>=ne1,'x2>= ne'1 + ... + ne'n} u+ S_N0 u+ S_N1 u+ ... u+ S_Nn
+%E |- pat1 : t gives E_t1,S_N1 ... E |- patn : t gives E_tn,S_Nn
+%disjoint doms(E_t1 , ... , E_tn)
+%num1 lt ... lt numn
+%----------------------------------------------------------- :: indexedVectorInc
+%E |- [ num1 = pat1 , ... , numn = patn ] : vector :t_arg_nexp: 'x :t_arg_nexp: 'x2 inc t gives (E_t1 u+ ... u+ E_tn), {'x<=num1, 'x2 >= numn + (- num1)} u+ S_N1 u+ ... u+ S_Nn
+
+%E |- pat1 : t gives E_t1,S_N1 ... E |- patn : t gives E_tn,S_Nn
+%disjoint doms(E_t1 , ... , E_tn)
+%num1 gt ... gt numn
+%----------------------------------------------------------- :: indexedVectorDec
+%E |- [ num1 = pat1 , ... , numn = patn ] : vector :t_arg_nexp: 'x :t_arg_nexp: 'x2 dec t gives (E_t1 u+ ... u+ E_tn), {'x>=num1,'x2<=num1 +(-numn)} u+ S_N1 u+ ... u+ S_Nn
+
+%E |- pat1 : vector ne1 ne'1 inc t gives E_t1,S_N1 ... E |- patn : vector nen ne'n inc t gives E_tn,S_Nn
+%disjoint doms(E_t1 , ... , E_tn)
+%S_N0 = consistent_increase ne1 ne'1 ... nen ne'n
+%----------------------------------------------------------- :: vectorConcatInc
+%E |- pat1 : ... : patn : vector :t_arg_nexp: 'x :t_arg_nexp: 'x2 inc t gives (E_t1 u+ ... u+ E_tn),{'x<=ne1,'x2>= ne'1 + ... + ne'n} u+ S_N0 u+ S_N1 u+ ... u+ S_Nn
+
+%E |- pat1 : vector ne1 ne'1 dec t gives E_t1,S_N1 ... E |- patn : vector nen ne'n dec t gives E_tn,S_Nn
+%disjoint doms(E_t1 , ... , E_tn)
+%S_N0 = consistent_decrease ne1 ne'1 ... nen ne'n
+%----------------------------------------------------------- :: vectorConcatDec
+%E |- pat1 : ... : patn : vector :t_arg_nexp: 'x :t_arg_nexp: 'x2 inc t gives (E_t1 u+ ... u+ E_tn),{'x>=ne1,'x2>= ne'1 + ... + ne'n} u+ S_N0 u+ S_N1 u+ ... u+ S_Nn
E |- pat1 : t1 gives E_t1,S_N1 .... E |- patn : tn gives E_tn,S_Nn
disjoint doms(E_t1,....,E_tn)
@@ -993,7 +1086,7 @@ id NOTIN dom(E_t)
E_t(id) gives t1 -> t {</base_effecti//i/>, wmem, </base_effect'j//j/>} Extern {}
<E_t,E_d> |- exp : t1 gives I,E_t1
---------------------------------------------------------- :: wmem
-<E_t,E_d> |- id exp : t gives I u+ <{},{wmem}>,E_t
+<E_t,E_d> |- :LEXP_memory: id(exp) : t gives I u+ <{},{wmem}>,E_t
E |- exp : enum ne1 ne2 order gives I1,E_t
E |- lexp : vector ne3 ne4 order t gives I2,E_t
@@ -1012,8 +1105,8 @@ E |- lexp : vector ne5 ne6 order t gives I3,E_t
---------------------------------------------------------- :: wslice_spread
E |- lexp [exp1 : exp2] : t gives I1 u+ I2 u+ I3 u+ <{ne5<=ne1, ne1+ne2 <= ne3, ne3+ne4<= ne5+ne6},pure> ,E_t
-E_r (id1 t_args) gives </idi : ti//i/> id : t </id'j : t'j//j/>
-<E_t,<E_k,E_r,E_e>> |- lexp : id1 t_args gives I,E_t
+E_r (id'' t_args) gives </idi : ti//i/> id : t </id'j : t'j//j/>
+<E_t,<E_k,E_r,E_e>> |- lexp : id'' t_args gives I,E_t
---------------------------------------------------------- :: wrecord
<E_t,<E_k,E_r,E_e>> |- lexp.id : t gives I,E_t
@@ -1055,9 +1148,9 @@ E_d |- typedef id name_scm_opt = const struct { typ1 id1 ; .. ; typn idn semi_op
<E_k u+ </E_ki//i/>,E_r,E_e> |- typ1 ~> t1 .. <E_k u+ </E_ki//i/>,E_r,E_e> |- typn ~> tn
{ id'1 |-> k1, .. ,id'm |-> km } = u+ </E_ki//i/>
E_r1 = { {id1:t1, .., idn:tn} |-> {id'1 |-> k1, ..,id'm |-> km}, u+</S_Ni//i/>, None, id :t_arg_typ: id'1 .. :t_arg_typ: id'm }
-E_k1 = { id |-> K_Lam (k1 .. km -> K_Typ) }
+E_k1' = { id |-> K_Lam (k1 .. km -> K_Typ) }
----------------------------------------------------------- :: quant_record
-<E_k,E_r,E_e> |- typedef id name_scm_opt = const struct forall </quant_itemi//i/> . { typ1 id1 ; .. ; typn idn semi_opt } gives <{},<E_k1,E_r1,{}>>
+<E_k,E_r,E_e> |- typedef id name_scm_opt = const struct forall </quant_itemi//i/> . { typ1 id1 ; .. ; typn idn semi_opt } gives <{},<E_k',E_r1,{}>>
E_t = { id1 |-> t1 -> :T_id: id pure Ctor {}, ..., idn |-> tn -> :T_id: id pure Ctor {} }
E_k1 = { id |-> K_Typ }
@@ -1067,12 +1160,12 @@ E_k1 = { id |-> K_Typ }
</ <E_k,E_r,E_e> |- quant_itemi ~> E_ki, S_Ni//i/>
{ id'1 |-> k1, ... , id'm |-> km } = u+ </E_ki//i/>
-E_k1 = { id |-> K_Lam (k1 ... km -> K_Typ) } u+ </E_ki//i/>
-<E_k u+ E_k1,E_r,E_e> |- typ1 ~> t1 ... <E_k u+ E_k1,E_r,E_e> |- typn ~> tn
+E_k' = { id |-> K_Lam (k1 ... km -> K_Typ) } u+ </E_ki//i/>
+<E_k u+ E_k',E_r,E_e> |- typ1 ~> t1 ... <E_k u+ E_k',E_r,E_e> |- typn ~> tn
t = id :t_arg_typ: id'1 ... :t_arg_typ: id'm
-E_t = { id1 |-> E_k1, u+</S_Ni//i/>, Ctor, t1 -> t pure Ctor {}, ... , idn |-> E_k1, u+</S_Ni//i/>, Ctor, tn -> t pure Ctor {} }
+E_t = { id1 |-> E_k', u+</S_Ni//i/>, Ctor, t1 -> t pure Ctor {}, ... , idn |-> E_k', u+</S_Ni//i/>, Ctor, tn -> t pure Ctor {} }
------------------------------------------------------------ :: quant_union
-<E_k,E_r,E_e> |- typedef id name_scm_opt = const union forall </quant_itemi//i/> . { typ1 id1 ; ... ; typn idn semi_opt } gives <E_t,<E_k1,{},{}>>
+<E_k,E_r,E_e> |- typedef id name_scm_opt = const union forall </quant_itemi//i/> . { typ1 id1 ; ... ; typn idn semi_opt } gives <E_t,<E_k',{},{}>>
% Save these as enumerations for coercion
E_t = {id1 |-> id, ..., idn |-> id}
@@ -1085,61 +1178,61 @@ E |- fundef gives E_t , S_N :: :: check_fd :: check_fd_
{{ com Check a function definition }}
by
-E_t(id) gives E_k1,S_N1,None, t1 -> t effect None S_N1
+E_t(id) gives E_k',S_N',None, t1 -> t effect None S_N'
</E_d |- quant_itemi ~> E_ki,S_Ni//i/>
-S_N2 = u+ </S_Ni//i/>
-E_k1 ~= </E_ki//i/>
-E_d1 = <E_k1,{},{}> u+ E_d
+S_N'' = u+ </S_Ni//i/>
+E_k' ~= </E_ki//i/>
+E_d1 = <E_k',{},{}> u+ E_d
E_d1 |- typ ~> t
-</<E_t,E_d1> |- patj : t1 gives E_tj,S_N'j//j/>
-</<(E_t u+ E_tj),E_d1> |- expj : t gives <S_N''j,effect'j>,E_t'j//j/>
-S_N3 = u+ </S_N'j u+ S_N''j//j/>
+</<E_t,E_d1> |- patj : t1 gives E_tj,S_N'''j//j/>
+</<(E_t u+ E_tj),E_d1> |- expj : t gives <S_N''''j,effect'j>,E_t'j//j/>
+S_N''''' = u+ </S_N'''j u+ S_N''''j//j/>
effect = u+ </effect'j//j/>
-S_N = resolve ( S_N1 u+ S_N2 u+ S_N3)
+S_N = resolve ( S_N' u+ S_N'' u+ S_N''''')
------------------------------------------------------------- :: rec_function
<E_t,E_d> |- function rec forall </quant_itemi//i/> . typ effectkw effect </id patj = expj//j/> gives E_t, S_N
-E_t(id) gives t1 -> t effect None S_N1
+E_t(id) gives t1 -> t effect None S_N'
E_d |- typ ~> t
-</<E_t,E_d> |- patj : t1 gives E_tj,S_N'j//j/>
-</<(E_t u+ E_tj),E_d> |- expj : t gives <S_N''j,effect'j>,E_t'j//j/>
+</<E_t,E_d> |- patj : t1 gives E_tj,S_N''j//j/>
+</<(E_t u+ E_tj),E_d> |- expj : t gives <S_N'''j,effect'j>,E_t'j//j/>
effect = u+ </effect'j//j/>
-S_N = resolve (S_N1 u+ </S_N'j u+ S_N''j//j/>)
+S_N = resolve (S_N' u+ </S_N''j u+ S_N'''j//j/>)
------------------------------------------------------------- :: rec_function2
<E_t,E_d> |- function rec typ effectkw effect </id patj = expj//j/> gives E_t, S_N
</<E_k,E_r,E_e> |- quant_itemi ~> E_ki,S_Ni//i/>
-S_N1 = u+ </S_Ni//i/>
-E_k2 = E_k u+ </E_ki//i/>
-<E_k2,E_r,E_e> |- typ ~> t
-</<E_t,<E_k2,E_r,E_e>> |- patj : t1 gives E_tj,S_N'j//j/>
-E_t2 = (E_t u+ {id |-> t1 -> t effect None S_N1})
-</<(E_t2 u+ E_tj),<E_k2,E_r,E_e>> |- expj : t gives <S_N'j,effect'j>,E_t'j//j/>
+S_N' = u+ </S_Ni//i/>
+E_k' = E_k u+ </E_ki//i/>
+<E_k',E_r,E_e> |- typ ~> t
+</<E_t,<E_k',E_r,E_e>> |- patj : t1 gives E_tj,S_N''j//j/>
+E_t' = (E_t u+ {id |-> t1 -> t effect None S_N'})
+</<(E_t' u+ E_tj),<E_k',E_r,E_e>> |- expj : t gives <S_N'''j,effect'j>,E_t'j//j/>
effect = u+ </effect'j//j/>
-S_N = resolve (S_N1 u+ </S_N'j u+ S_N''j//j/>)
+S_N = resolve (S_N' u+ </S_N''j u+ S_N'''j//j/>)
------------------------------------------------------------- :: rec_function_no_spec
-<E_t,<E_k,E_r,E_e>> |- function rec forall </quant_itemi//i/> . typ effectkw effect </id patj = expj//j/> gives E_t2, S_N
+<E_t,<E_k,E_r,E_e>> |- function rec forall </quant_itemi//i/> . typ effectkw effect </id patj = expj//j/> gives E_t', S_N
E_d |- typ ~> t
</<E_t,E_d> |- patj : t1 gives E_tj,S_N'j//j/>
-E_t2 = (E_t u+ {id |-> t1 -> t effect None {}})
-</<(E_t2 u+ E_tj),E_d> |- expj : t gives <S_N'j,effect'j>,E_t'j//j/>
+E_t' = (E_t u+ {id |-> t1 -> t effect None {}})
+</<(E_t' u+ E_tj),E_d> |- expj : t gives <S_N'j,effect'j>,E_t'j//j/>
effect = u+ </effect'j//j/>
S_N = resolve (u+ </S_N'j u+ S_N''j//j/>)
------------------------------------------------------------- :: rec_function_no_spec2
-<E_t,E_d> |- function rec typ effectkw effect </id patj = expj//j/> gives E_t2, S_N
+<E_t,E_d> |- function rec typ effectkw effect </id patj = expj//j/> gives E_t', S_N
-t2 = t1 -> t effect None S_N1
-E_t(id) gives E_k1,S_N1,None, t2
+t2 = t1 -> t effect None S_N'
+E_t(id) gives E_k',S_N',None, t2
</<E_k,E_r,E_e> |- quant_itemi ~> E_ki,S_Ni//i/>
-S_N2 = u+ </S_Ni//i/>
-E_k1 ~= </E_ki//i/>
-<E_k1 u+ E_k,E_r,E_e> |- typ ~> t
-</<E_t,<E_k u+ E_k1,E_r,E_e>> |- patj : t1 gives E_tj,S_N'j//j/>
-</<(E_t u- {id |-> t2} u+ E_tj),<E_k u+ E_k1,E_r,E_e>> |- expj : t gives <S_N''j,effect'j>,E_t'j//j/>
-S_N3 = u+ </S_N'j u+ S_N''j//j/>
+S_N'' = u+ </S_Ni//i/>
+E_k'' ~= </E_ki//i/>
+<E_k'' u+ E_k,E_r,E_e> |- typ ~> t
+</<E_t,<E_k u+ E_k'',E_r,E_e>> |- patj : t1 gives E_tj,S_N''j//j/>
+</<(E_t u- {id |-> t2} u+ E_tj),<E_k u+ E_k'',E_r,E_e>> |- expj : t gives <S_N'''j,effect'j>,E_t'j//j/>
+S_N'''' = u+ </S_N''j u+ S_N'''j//j/>
effect = u+ </effect'j//j/>
-S_N = resolve ( S_N1 u+ S_N2 u+ S_N3)
+S_N = resolve ( S_N' u+ S_N'' u+ S_N'''')
------------------------------------------------------------- :: function
<E_t,<E_k,E_r,E_e>> |- function forall </quant_itemi//i/> . typ effectkw effect </id patj = expj//j/> gives E_t, S_N
@@ -1153,25 +1246,25 @@ S_N = resolve (S_N1 u+ </S_N'j u+ S_N''j//j/>)
<E_t,E_d> |- function typ effectkw effect </id patj = expj//j/> gives E_t, S_N
</<E_k,E_r,E_e> |- quant_itemi ~> E_ki,S_Ni//i/>
-S_N1 = u+ </S_Ni//i/>
-E_k2 = E_k u+ </E_ki//i/>
-<E_k2,E_r,E_e> |- typ ~> t
-</<E_t,<E_k2,E_r,E_e>> |- patj : t1 gives E_tj,S_N'j//j/>
-E_t2 = (E_t u+ {id |-> t1 -> t effect None S_N1})
-</<(E_t u+ E_tj),<E_k2,E_r,E_e>> |- expj : t gives <S_N'j,effect'j>,E_t'j//j/>
+S_N' = u+ </S_Ni//i/>
+E_k'' = E_k u+ </E_ki//i/>
+<E_k'',E_r,E_e> |- typ ~> t
+</<E_t,<E_k'',E_r,E_e>> |- patj : t1 gives E_tj,S_N''j//j/>
+E_t' = (E_t u+ {id |-> t1 -> t effect None S_N'})
+</<(E_t u+ E_tj),<E_k'',E_r,E_e>> |- expj : t gives <S_N''j,effect'j>,E_t'j//j/>
effect = u+ </effect'j//j/>
-S_N = resolve (S_N1 u+ </S_N'j u+ S_N''j//j/>)
+S_N = resolve (S_N' u+ </S_N'j u+ S_N''j//j/>)
------------------------------------------------------------- :: function_no_spec
-<E_t,<E_k,E_r,E_e>> |- function forall </quant_itemi//i/> . typ effectkw effect </id patj = expj//j/> gives E_t2, S_N
+<E_t,<E_k,E_r,E_e>> |- function forall </quant_itemi//i/> . typ effectkw effect </id patj = expj//j/> gives E_t', S_N
E_d |- typ ~> t
</<E_t,E_d> |- patj : t1 gives E_tj,S_N'j//j/>
-E_t2 = (E_t u+ {id |-> t1 -> t effect None S_N})
+E_t' = (E_t u+ {id |-> t1 -> t effect None S_N})
</<(E_t u+ E_tj),E_d> |- expj : t gives <S_N'j,effect'j>,E_t'j//j/>
effect = u+ </effect'j//j/>
S_N = resolve (u+ </S_N'j u+ S_N''j//j/>)
------------------------------------------------------------- :: function_no_spec2
-<E_t,E_d> |- function typ effectkw effect </id patj = expj//j/> gives E_t2, S_N
+<E_t,E_d> |- function typ effectkw effect </id patj = expj//j/> gives E_t', S_N
defn
diff --git a/src/type_internal.ml b/src/type_internal.ml
index b019624d..bfed90ee 100644
--- a/src/type_internal.ml
+++ b/src/type_internal.ml
@@ -81,3 +81,6 @@ let initial_kind_env =
("enum", {k = K_Lam( [ {k = K_Nat}; {k= K_Nat}; {k=K_Ord} ], {k = K_Typ}) });
("vector", {k = K_Lam( [ {k = K_Nat}; {k = K_Nat}; {k= K_Ord} ; {k=K_Typ}], {k=K_Typ}) } )
]
+
+let rec type_eq l t1 t2 = (t2,[])
+let rec type_coerce l t1 t2 = (t2,[])
diff --git a/src/type_internal.mli b/src/type_internal.mli
index fedc5cc4..2e8c3418 100644
--- a/src/type_internal.mli
+++ b/src/type_internal.mli
@@ -68,3 +68,9 @@ type nexp_range =
type tannot = (t * tag * nexp_range list) option
val initial_kind_env : kind Envmap.t
+
+(* type_eq mutates to unify variables, and will raise an exception if two types cannot be equal *)
+val type_eq : Parse_ast.l -> t -> t -> t * nexp_range list
+
+(* type_eq mutates to unify variables, and will raise an exception if the first type cannot be coerced into the second *)
+val type_coerce : Parse_ast.l -> t -> t -> t * nexp_range list