(∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ Signatures
∗)
(∗∗Datatype definitions :
A signature [ sig ] is a list of bundles of mutually recursive Type (or Prop) declarations. A bundle [bundle] is either a list of datatype definitions [data decl] or an assertion Each data declaration contains:
−a Type (or Prop) constructor [ tctr ] identifier . −the kind of the Type/Prop being declared
−a list of constructor [ ctr ] declarations [ ctr decls ]
CONVENTION: We use the notation [tctr] to refer to a Type or Prop constructor identifier . We use the notation [ ctr ] to refer to an exp or proof constructor identifier . Both [ tctr ] and [ ctr ] values have Coq type [ctr ] (both ranged over by [c ]) ∗)
(∗ Definition of datatype declarations in the context ∗)
Definition ctr decls := list ( ctr ∗ tm).
Definitiondata decl := ( ctr ∗ tm∗ (option ctr decls ) )%type.
Definitiondefns := list data decl.
Inductive bundle : Set := | bundle defns : defns→bundle | bundle assert : ctr →tm→bundle .
Definition sig := list (bundle).
(∗ Utilities for working with signatures∗)
Definitiondom ctr decls(L:ctr decls ) :=
List .map (fun(x:ctr∗tm)⇒let (n, ) := x in n) L.
Fixpointctr decls lookup (c: ctr ) ( cdl : ctr decls ) {struct cdl}: option tm :=
matchcdlwith
| nil ⇒None
| (c ’, t ) :: cdl ⇒
if (eq ctr dec c c ’) thenSome t
elsectr decls lookup c cdl
end.
Fixpointbundle defns ctr lookup (c: ctr ) (defns: defns) {struct defns}: option tm :=
matchdefnswith
| (c ’, t , None)::ds⇒
if (eq ctr dec c c ’) thenSome t
elsebundle defns ctr lookup c ds | (c ’, t , Some cdl)::ds⇒
if (eq ctr dec c c ’) thenSome t
else matchctr decls lookup c cdl with
| None⇒bundle defns ctr lookup c ds | Some t⇒Some t
end end.
(∗ Gets the kind/type associated with constructor c in signature S Returns:
[None] if c isn ’ t in S
[Some t] if c’s kind/type is t in S ∗)
Fixpointsig lookup ctr (c: ctr ) (S:sig) {struct S}: option tm :=
matchSwith
| nil ⇒None
| b :: bs⇒matchbwith
| bundle defns defns⇒
matchbundle defns ctr lookup c defnswith
| Some t⇒Some t
| None⇒sig lookup ctr c bs
end
| bundle assert ⇒ sig lookup ctr c bs
end end.
(∗ Gets the kind/type associated with an assertion c in signature S returns: [None] if c isn ’ t in S
[Some t] if c’s kind/type is t in S ∗)
Fixpointsig lookup assn (c: ctr ) (S:sig) {struct S}: option tm :=
matchSwith
| nil ⇒None
| b :: bs⇒matchbwith
| bundle defns defns⇒sig lookup assn c bs | bundle assert c’ t ⇒
if eq ctr dec c c’ thenSome telsesig lookup assn c bs
end end.
Definition ctr decls has (c: ctr ) ( t :tm) ( cdl : ctr decls ) := ctr decls lookup c cdl = Some t.
Definitiondefns has ctr (c: ctr ) (tp : tm) (d:defns) := bundle defns ctr lookup c d = Some tp.
Definition sig has ctr (c: ctr ) ( t :tm) (S:sig) : Prop:= sig lookup ctr c S = Some t.
Definitionsig has assn (c: ctr ) ( t :tm) (S:sig) : Prop:= sig lookup assn c S = Some t.
Fixpointget defns ctrs of (c: ctr ) (d:defns){struct d} : option ( list ctr ) :=
matchdwith
| nil ⇒None
| (c ’, t , cdl ) :: ds⇒
if eq ctr dec c c’
then matchcdlwith
| None⇒None
| Some cdl’⇒Some (dom ctr decls cdl’)
end
else get defns ctrs of c ds
end.
(∗ Gets the list of expression constructors for type c from the signature S. Returns: [None] if c is temporarily undefined in S
[Some None] if c is not defined in
[Some l], where l is the list of term constructors, otherwise ∗)
Fixpoint get ctrs of (c: ctr ) (S:sig) {struct S}: option ( list ctr ) :=
matchSwith
| nil ⇒None
| b :: bs⇒matchbwith
| bundle defns d⇒
matchget defns ctrs of c dwith
| Some l⇒Some l | None⇒get ctrs of c bs
end
| bundle assert ⇒ get ctrs of c bs
end end.
Definition get tctr defns of (d:defns) : defns :=
let strip x :=
matchxwith(n,t, ) ⇒(n, t ,None)end in
List .map strip d.
Fixpointdom defns (d:defns){struct d}: list ctr :=
matchdwith
| nil ⇒ nil
| (c, ,None)::ds⇒c ::( dom defns ds)
| (c, ,Some cdl)::ds⇒c ::( dom ctr decls cdl)++(dom defns ds)
end.
matchbwith
| bundle defns d⇒dom defns d | bundle assert c t ⇒c :: nil
end.
Definitiondom sig (S: sig) : list ctr := List .flat map (dom bundle) S.
Inductiveis tm arr : tm→Prop:=
| is tm arr arr : forall t1 t2 U, is tm arr (tm arr t1 t2 U) .
(∗ [constructs tm s] is intended to hold when [tm] has form [ t1 → ... →tn →s] and s is not an arrow∗)
Inductiveconstructs : tm→tm→Prop:=
| constructs base : forall s, ˜( is tm arr s) →constructs s s | constructs arr : forall s t1 t2 ,
constructs t2 s →constructs (tm arr t1 t2 STM WORLD BOT) s.
Inductive fully applied args : tm→ctr → list tm→Prop:=
| fully applied args ctr : forall c, fully applied args ( tm ctr c) c nil | fully applied args app : forall t tn c args,
fully applied args t c args→
fully applied args (tm app t tn) c (tn :: args) .
Inductive fully applied typ : tm→ctr →tm→Prop:=
| fully applied TYPE : forall c, fully applied typ ( tm ctr c) c K TYPE | fully applied PROP : forall c, fully applied typ ( tm ctr c) c K PROP | fully applied typ app : forall k1 k2 t tn c,
fully applied typ t c k2→
fully applied typ (tm app t tn) c (tm arr k1 k2 STM WORLD BOT) .
(∗
∗ All tm bv holds when the list of terms consists entirely of bound variables. ∗)
(∗ The ordering of bound variables are relevant∗)
Inductiveall tm bv : nat →( list tm)→ Prop:= | all tm bv nil : forall n, all tm bv n nil
| all tm bv cons : forall l n, all tm bv (n+1) l →all tm bv n (( tm bv n) :: l ) . (∗ has level t n if t = t1 → ... →tn →s∗)
Inductivehas level: tm→nat →Prop:=
| has level base: forall u, ˜ is tm arr u→has level u 0 | has level arr : forall u n t U,
has level u n→has level (tm arr t u U) (1+n). (∗ ctrs of t = l where l is a list of (posibly non−unique)
nats where each n in l occurence in t as ( tm ctr n) ∗) Fixpoint ctrs of ( t :tm) : list ctr := matchtwith | tm fv ⇒ nil | tm bv ⇒ nil | tm con ⇒ nil | tm ctr c ⇒c :: nil | tm app t1 t2 ⇒( ctrs of t1) ++ ( ctrs of t2) | tm mapp t1 t2 ⇒( ctrs of t1) ++ ( ctrs of t2) | tm prin ⇒ nil | tm abs t1 t2 U ⇒( ctrs of t1) ++ ( ctrs of t2) ++ ( ctrs of U) | tm arr t1 t2 U ⇒( ctrs of t1) ++ ( ctrs of t2) ++ ( ctrs of U) | tm mat t1 t2 t3 ⇒( ctrs of t1) ++ ( ctrs of t2) ++ ( ctrs of t3) | tm brn c t2 t3 ⇒( ctrs of t2) ++ ( ctrs of t3) | tm cast t1 t2 t3 ⇒( ctrs of t1) ++ ( ctrs of t2) ++ ( ctrs of t3)
| tm enc ⇒ nil (∗ encryptions are opaque∗)
| tm letat t1 t2 t3 ⇒( ctrs of t1) ++ ( ctrs of t2) ++ ( ctrs of t3) | tm forbnd t1 t2 t3 ⇒( ctrs of t1) ++ ( ctrs of t2) ++ ( ctrs of t3)
end.
Definition disjoint (L1 L2: list ctr ) := forall n, (In n L1)→ ˜( In n L2). (∗ [ positive (n 1, ... n m) t ] is intended to hold
when construtor application of [ n i ] appear at most positively in [ t ]. As definied this judgment is very conservative∗)
Inductivepositive ( ctrs : list ctr ) : tm→Prop:= | positive arr : forall t1 t2 U,
disjoint ctrs ( ctrs of t1) → positive ctrs t2
→ positive ctrs (tm arr t1 t2 U) | positive app: forall t1 t2 ,
positive ctrs t1
→ disjoint ctrs ( ctrs of t2) → positive ctrs (tm app t1 t2) | postive ctr : forall n,
positive ctrs ( tm ctr n).
Inductivebranches cover aux : ( list ctr ) →tm→Prop:= | bca nil : branches cover aux nil TM NONE
| bca cons : forall c l t branches,
branches cover aux l branches→
branches cover aux (c::l ) (tm brn c t branches).
(∗ [branches cover S branches ctr] is intended to hold when [branches] contains exactly one [tm brn] per term constructor which creates a [ ctr ]. ∗)
Definitionbranches cover (S:sig) (branches:tm) (ctr : ctr ) : Prop:=