Definition: Paxos-spec8-spec71
VoteState ==  (let a,r,bv in <<a, r>bv> where from x1)

Definition: Paxos-spec8-spec72
VoteState ==  (let a,r,bv in <<a, r>bv> where from x1)

Definition: Paxos-spec8-spec73
Collect1 ==  es-collect-opt-max(x1; x2; x3 1; vs.fst(snd(vs)); vs.snd(snd(vs)))

Definition: Paxos-spec8-spec74
Proposal ==  λtr.let b,b',v tr in if b' <then inl <b, v> else inr ⋅  fi [Collect1]

Definition: Paxos-spec8-spec75
NoProposal ==  λtr.let b,b',v tr in if b ≤b' then inl else inr ⋅  fi [Collect1]

Definition: Paxos-spec8-spec76
MaxReserve ==  es-interface-accum(λmx,x. imax(mx;snd(x));0;x1)

Definition: Paxos-spec8-spec77
AcceptOrReject ==  (let lbv,m lbvm in let l,b,v lbv in <lbv, m ≤b> where lbvm from (MaxReserve'?-1) when x2)

Definition: Paxos-spec8-spec78
AcceptOrRejectTaggedTrue ==  Tagged_tt(AcceptOrReject)

Definition: Paxos-spec8-spec79
Accept ==  λtr.(inl (snd(tr)))[AcceptOrRejectTaggedTrue]

Definition: Paxos-spec8-spec710
MaxAccept ==  accum-class(bv1,bv2.if fst(bv1) <fst(bv2) then bv2 else bv1 fi bv.bv; Accept)

Definition: Paxos-spec8-spec711
Vote ==  ((inl bv where bv from MaxAccept)'?inr ⋅ when x1

Definition: Paxos-spec8-spec712
Vote' ==  (let a,b,ok in <<a, b>ok> where from x1)

Definition: Paxos-spec8-spec713
Collect2 ==
  es-collect-filter-max(x1; x2 1; vs.fst(snd(vs)); vs.tt; vs.case snd(snd(vs)) of inl(p) => fst(p) inr(x) => -1)

Definition: Paxos-spec8-spec714
Collect3 ==  es-collect-filter-max(VoteState; x2 1; vs.Reservation(vs); vs.tt; vs.Ballot(vs))

Definition: Paxos-spec8-spec715
AccOrRej ==  (<snd(fst(v)), snd(v)> where from AcceptOrReject)

Definition: Paxos-spec8-spec716
Acc ==  Tagged_tt(AccOrRej)

Definition: Paxos-spec8-spec717
abbreviation(x1;x2) ==  (inl bv where bv from MaxAccept)

Definition: IdLnk
IdLnk ==  Id × Id × Id

Lemma: IdLnk_wf
IdLnk ∈ Type

Lemma: IdLnk_sq
SQType(IdLnk)

Definition: mklnk
link $n from $a to $b ==  <"$a", "$b", "$n">

Lemma: mklnk-wf-test
link from to b ∈ IdLnk

Definition: mk_lnk
(link(n) from to j) ==  <i, j, n>

Lemma: mk_lnk_wf
[i,j,n:Id].  ((link(n) from to j) ∈ IdLnk)

Lemma: free-from-atom-IdLnk
[a:Atom1]. ∀[l:IdLnk].  a#l:IdLnk

Definition: lnk-inv
lnk-inv(l) ==  <fst(snd(l)), fst(l), snd(snd(l))>

Lemma: lnk-inv_wf
[l:IdLnk]. (lnk-inv(l) ∈ IdLnk)

Lemma: lnk-inv-inv
[l:IdLnk]. (lnk-inv(lnk-inv(l)) l ∈ IdLnk)

Lemma: lnk-inv-one-one
[l1,l2:IdLnk].  uiff(lnk-inv(l1) lnk-inv(l2) ∈ IdLnk;l1 l2 ∈ IdLnk)

Definition: Msg
Msg(M) ==  l:IdLnk × t:Id × (M t)

Lemma: Msg_wf
[M:IdLnk ⟶ Id ⟶ Type]. (Msg(M) ∈ Type)

Definition: msg
msg(l;t;v) ==  <l, t, v>

Lemma: msg_wf
[M:IdLnk ⟶ Id ⟶ Type]. ∀[l:IdLnk]. ∀[t:Id]. ∀[v:M t].  (msg(l;t;v) ∈ Msg(M))

Definition: mlnk
mlnk(m) ==  fst(m)

Lemma: mlnk_wf
[M:IdLnk ⟶ Id ⟶ Type]. ∀[m:Msg(M)].  (mlnk(m) ∈ IdLnk)

Definition: mtag
mtag(m) ==  fst(snd(m))

Lemma: mtag_wf
[M:IdLnk ⟶ Id ⟶ Type]. ∀[m:Msg(M)].  (mtag(m) ∈ Id)

Definition: mval
mval(m) ==  snd(snd(m))

Lemma: mval_wf
[M:IdLnk ⟶ Id ⟶ Type]. ∀[m:Msg(M)].  (mval(m) ∈ mlnk(m) mtag(m))

Definition: haslink
haslink(l;m) ==  mlnk(m) l ∈ IdLnk

Lemma: haslink_wf
[M:IdLnk ⟶ Id ⟶ Type]. ∀[l:IdLnk]. ∀[m:Msg(M)].  (haslink(l;m) ∈ ℙ)

Definition: Msg_sub
Msg_sub(l;M) ==  {m:Msg(M)| haslink(l;m)} 

Lemma: Msg_sub_wf
[M:IdLnk ⟶ Id ⟶ Type]. ∀[l:IdLnk].  (Msg_sub(l;M) ∈ Type)

Definition: Knd
Knd ==  IdLnk × Id Id

Lemma: Knd_wf
Knd ∈ Type

Lemma: Knd_sq
SQType(Knd)

Definition: Kind
Kind ==  IdLnk × Id (Id × Id)

Lemma: Kind_wf
Kind ∈ Type

Lemma: Kind_sq
SQType(Kind)

Definition: event-data
EventData(M) ==  k:Kind × (M k)

Lemma: event-data_wf
[M:Kind ⟶ Type]. (EventData(M) ∈ Type)

Lemma: free-from-atom-Knd
[a:Atom1]. ∀[k:Knd].  a#k:Knd

Definition: isrcv
isrcv(k) ==  isl(k)

Lemma: isrcv_wf
[k:Knd]. (isrcv(k) ∈ 𝔹)

Definition: islocal
islocal(k) ==  ¬bisl(k)

Lemma: islocal_wf
[k:Knd]. (islocal(k) ∈ 𝔹)

Lemma: islocal-not-isrcv
[k:Knd]. (islocal(k) ~ ¬bisrcv(k))

Definition: rcv
rcv(l,tg) ==  inl <l, tg>

Lemma: rcv_wf
[l:IdLnk]. ∀[tg:Id].  (rcv(l,tg) ∈ Knd)

Definition: locl
locl(a) ==  inr 

Lemma: locl_wf
[a:Id]. (locl(a) ∈ Knd)

Lemma: locl_one_one
[a,b:Id].  b ∈ Id supposing locl(a) locl(b) ∈ Knd

Lemma: rcv_one_one
[l1,l2:IdLnk]. ∀[tg1,tg2:Id].  {(l1 l2 ∈ IdLnk) ∧ (tg1 tg2 ∈ Id)} supposing rcv(l1,tg1) rcv(l2,tg2) ∈ Knd

Lemma: not_rcv_locl
[a:Id]. ∀[l:IdLnk]. ∀[tg:Id].  False supposing rcv(l,tg) locl(a) ∈ Knd

Lemma: not_locl_rcv
[a:Id]. ∀[l:IdLnk]. ∀[tg:Id].  False supposing locl(a) rcv(l,tg) ∈ Knd

Definition: lnk
lnk(k) ==  fst(outl(k))

Lemma: lnk_wf
[k:Knd]. lnk(k) ∈ IdLnk supposing ↑isrcv(k)

Definition: tagof
tag(k) ==  snd(outl(k))

Lemma: tagof_wf
[k:Knd]. tag(k) ∈ Id supposing ↑isrcv(k)

Definition: actof
act(k) ==  outr(k)

Lemma: actof_wf
[k:Knd]. act(k) ∈ Id supposing ↑islocal(k)

Lemma: lnk_rcv_lemma
tg,l:Top.  (lnk(rcv(l,tg)) l)

Lemma: tag_rcv_lemma
tg,l:Top.  (tag(rcv(l,tg)) tg)

Lemma: act_locl_lemma
a:Top. (act(locl(a)) a)

Lemma: isrcv_rcv_lemma
tg,l:Top.  (isrcv(rcv(l,tg)) tt)

Lemma: isrcv_locl_lemma
a:Top. (isrcv(locl(a)) ff)

Lemma: local_or_rcv
k:Knd. ((↑islocal(k)) ∨ (↑isrcv(k)))

Lemma: islocal-implies
[k:Knd]. locl(act(k)) k ∈ Knd supposing ↑islocal(k)

Definition: kindcase
kindcase(k;a.f[a];l,t.g[l; t]) ==  if islocal(k) then f[act(k)] else g[lnk(k); tag(k)] fi 

Lemma: kindcase_wf
[B:Type]. ∀[k:Knd]. ∀[f:Id ⟶ B]. ∀[g:IdLnk ⟶ Id ⟶ B].  (kindcase(k;a.f[a];l,t.g[l;t]) ∈ B)

Lemma: kindcase-locl
[k:Knd]. ∀[f,g:Top].  kindcase(k;a.f[a];l,t.g[l;t]) f[act(k)] supposing ↑islocal(k)

Lemma: kindcase-rcv
[k:Knd]. ∀[f,g:Top].  kindcase(k;a.f[a];l,t.g[l;t]) g[lnk(k);tag(k)] supposing ¬↑islocal(k)

Definition: kind-rename
kind-rename(ra;rt;k) ==  kindcase(k;a.locl(ra a);l,tg.rcv(l,rt tg))

Lemma: kind-rename_wf
[ra,rt:Id ⟶ Id]. ∀[k:Knd].  (kind-rename(ra;rt;k) ∈ Knd)

Lemma: kind-rename-inj
[ra,rt:Id ⟶ Id].  (Inj(Knd;Knd;λk.kind-rename(ra;rt;k))) supposing (Inj(Id;Id;ra) and Inj(Id;Id;rt))

Definition: msg-rename
msg-rename(rtinv;m) ==  <fst(m), outl(rtinv (fst(snd(m)))), snd(snd(m))>

Lemma: msg-rename_wf
[M:IdLnk ⟶ Id ⟶ Type]. ∀[rt:Id ⟶ Id]. ∀[rtinv:Id ⟶ (Id?)].
  ∀[m:Msg(M)]. msg-rename(rtinv;m) ∈ Msg(λl,tg. (M (rt tg))) supposing ↑isl(rtinv mtag(m)) 
  supposing inv-rel(Id;Id;rt;rtinv)

Definition: lsrc
source(l) ==  fst(l)

Lemma: lsrc_wf
[l:IdLnk]. (source(l) ∈ Id)

Definition: ldst
destination(l) ==  fst(snd(l))

Lemma: ldst_wf
[l:IdLnk]. (destination(l) ∈ Id)

Lemma: ldst_mk_lnk_lemma
n,j,i:Top.  (destination((link(n) from to j)) j)

Lemma: lsrc_mk_lnk_lemma
n,j,i:Top.  (source((link(n) from to j)) i)

Definition: lname
lname(l) ==  snd(snd(l))

Lemma: lname_wf
[l:IdLnk]. (lname(l) ∈ Id)

Lemma: lname_mk_lnk_lemma
n,j,i:Top.  (lname((link(n) from to j)) n)

Definition: links-from-to
links(tg) from srclocs to dstlocs ==  concat(map(λc.map(λv.(link(tg) from to c);srclocs);dstlocs))

Lemma: links-from-to_wf
[tg:Id]. ∀[srclocs,dstlocs:Id List].  (links(tg) from srclocs to dstlocs ∈ IdLnk List)

Lemma: member-links-from-to
tg:Id. ∀srclocs,dstlocs:Id List. ∀l:IdLnk.
  ((l ∈ links(tg) from srclocs to dstlocs)
  ⇐⇒ {(source(l) ∈ srclocs) ∧ (destination(l) ∈ dstlocs) ∧ (lname(l) tg ∈ Id)})

Definition: rcvs-on
Rcvs(tg) on links ==  map(λl.rcv(l,tg);links)

Lemma: rcvs-on_wf
[tg:Id]. ∀[links:IdLnk List].  (Rcvs(tg) on links ∈ {k:Knd| ↑isrcv(k)}  List)

Lemma: member-rcvs-on
tg:Id. ∀links:IdLnk List. ∀k:Knd.  ((k ∈ Rcvs(tg) on links) ⇐⇒ (↑isrcv(k)) ∧ (tag(k) tg ∈ Id) ∧ (lnk(k) ∈ links))

Lemma: rcvs-on-links-from-to
tg1,tg2:Id. ∀srclocs,dstlocs:Id List.
  (∀d∈dstlocs.(∀s∈srclocs.(∃k∈Rcvs(tg1) on links(tg2) from srclocs to dstlocs. (source(lnk(k)) s ∈ Id)
                 ∧ (destination(lnk(k)) d ∈ Id))))

Lemma: lsrc-inv
[l:IdLnk]. (source(lnk-inv(l)) destination(l))

Lemma: ldst-inv
[l:IdLnk]. (destination(lnk-inv(l)) source(l))

Definition: lpath
lpath(p) ==  ∀i:ℕ||p|| 1. ((destination(p[i]) source(p[i 1]) ∈ Id) ∧ (p[i 1] lnk-inv(p[i]) ∈ IdLnk)))

Lemma: lpath_wf
[p:IdLnk List]. (lpath(p) ∈ ℙ)

Lemma: lpath_cons
[l:IdLnk]. ∀[p:IdLnk List].
  uiff(lpath([l p]);lpath(p)
  ∧ (destination(l) source(hd(p)) ∈ Id) ∧ (hd(p) lnk-inv(l) ∈ IdLnk)) supposing ¬(||p|| 0 ∈ ℤ))

Definition: lconnects
lconnects(p;i;j) ==
  lpath(p)
  ∧ ((||p|| 0 ∈ ℤ (i j ∈ Id))
  ∧ ((¬(||p|| 0 ∈ ℤ))  ((i source(hd(p)) ∈ Id) ∧ (j destination(last(p)) ∈ Id)))

Lemma: lconnects_wf
[p:IdLnk List]. ∀[i,j:Id].  (lconnects(p;i;j) ∈ ℙ)

Lemma: lpath-members-connected
[p:IdLnk List]. ∀[i:ℕ||p||]. ∀[j:ℕ1].  lconnects(l_interval(p;j;i);source(p[j]);source(p[i])) supposing lpath(p)

Lemma: isrcv-implies
[k:Knd]. rcv(lnk(k),tag(k)) ∈ Knd supposing ↑isrcv(k)

Definition: tagged-list-messages
tagged-list-messages(s;v;L) ==  concat(map(λtgf.map(λx.<fst(tgf), x>;(snd(tgf)) v);L))

Lemma: tagged-list-messages_wf
[S,V:Type]. ∀[M:Id ⟶ Type]. ∀[s:S]. ∀[v:V]. ∀[L:(t:Id × (S ⟶ V ⟶ (M[t] List))) List].
  (tagged-list-messages(s;v;L) ∈ (t:Id × M[t]) List)

Lemma: tagged-list-messages-wf2
[S,V:Type]. ∀[M:Id ⟶ Type]. ∀[s:S]. ∀[v:V]. ∀[L:(t:Id × (S ⟶ V ⟶ (M[t] List))) List].
  (tagged-list-messages(s;v;L) ∈ (t:{tg:Id| M[tg]}  × M[t]) List)

Definition: tagged-messages
tagged-messages(l;s;v;L) ==  map(λx.<l, x>;tagged-list-messages(s;v;L))

Lemma: tagged-messages_wf
[S,V:Type]. ∀[M:IdLnk ⟶ Id ⟶ Type]. ∀[l:IdLnk]. ∀[s:S]. ∀[v:V]. ∀[L:(t:Id × (S ⟶ V ⟶ (M[l;t] List))) List].
  (tagged-messages(l;s;v;L) ∈ {m:Msg(M)| mlnk(m) l ∈ IdLnk}  List)

Definition: vlnk
link_x from to ==  <i, j, x>

Lemma: vlnk_wf
[i,j,x:Id].  (link_x from to j ∈ IdLnk)

Lemma: dst_vlnk_lemma
x,j,i:Top.  (destination(link_x from to j) j)

Lemma: src_vlnk_lemma
x,j,i:Top.  (source(link_x from to j) i)

Definition: idlnk-deq
IdLnkDeq ==  product-deq(Id;Id × Id;IdDeq;product-deq(Id;Id;IdDeq;IdDeq))

Lemma: idlnk-deq_wf
IdLnkDeq ∈ EqDecider(IdLnk)

Definition: eq_lnk
==  IdLnkDeq b

Lemma: eq_lnk_wf
[a,b:IdLnk].  (a b ∈ 𝔹)

Lemma: assert-eq-lnk
[a,b:IdLnk].  uiff(↑b;a b ∈ IdLnk)

Lemma: decidable__equal_IdLnk
a,b:IdLnk.  Dec(a b ∈ IdLnk)

Lemma: eq_lnk_self
[l:IdLnk]. tt

Definition: isrcvl
isrcvl(l;k) ==  isrcv(k) ∧b lnk(k) l

Lemma: isrcvl_wf
[k:Knd]. ∀[l:IdLnk].  (isrcvl(l;k) ∈ 𝔹)

Lemma: assert-isrcvl
[k:Knd]. ∀[l:IdLnk].  uiff(↑isrcvl(l;k);(↑isrcv(k)) ∧ (lnk(k) l ∈ IdLnk))

Definition: Kind-deq
KindDeq ==  union-deq(IdLnk × Id;Id;product-deq(IdLnk;Id;IdLnkDeq;IdDeq);IdDeq)

Lemma: Kind-deq_wf
KindDeq ∈ EqDecider(Knd)

Definition: eq_knd
==  KindDeq b

Lemma: eq_knd_wf
[a,b:Knd].  (a b ∈ 𝔹)

Lemma: eq_knd_self
[k:Knd]. (k tt)

Lemma: assert-eq-knd
[a,b:Knd].  uiff(↑b;a b ∈ Knd)

Lemma: decidable__equal_Kind
a,b:Knd.  Dec(a b ∈ Knd)

Lemma: lconnects-transitive
p,q:IdLnk List. ∀i,j,k:Id.  (∃r:IdLnk List. lconnects(r;i;k)) supposing (lconnects(q;j;k) and lconnects(p;i;j))

Definition: rcvset
rcvset(a;b;S;k) ==  isrcv(k) ∧b tag(k) b ∧b lname(lnk(k)) a ∧b source(lnk(k)) ∈b S ∧b destination(lnk(k)) ∈b S

Lemma: rcvset_wf
[a,b:Id]. ∀[S:Id List]. ∀[k:Knd].  (rcvset(a;b;S;k) ∈ 𝔹)

Lemma: assert-rcvset
a,b:Id. ∀S:Id List. ∀k:Knd.
  (↑rcvset(a;b;S;k) ⇐⇒ ∃i,j:Id. ((i ∈ S) ∧ (j ∈ S) ∧ (k rcv((link(a) from to j),b) ∈ Knd)))

Definition: graph-rcvset
graph-rcvset(a;b;S;G;k) ==
  isrcv(k)
  ∧b tag(k) b
  ∧b lname(lnk(k)) source(lnk(k)) destination(lnk(k))
  ∧b source(lnk(k)) ∈b S
  ∧b destination(lnk(k)) ∈b source(lnk(k))

Lemma: graph-rcvset_wf
[a:Id ⟶ Id ⟶ Id]. ∀[b:Id]. ∀[S:Id List]. ∀[G:Graph(S)]. ∀[k:Knd].  (graph-rcvset(a;b;S;G;k) ∈ 𝔹)

Lemma: assert-graph-rcvset
a:Id ⟶ Id ⟶ Id. ∀b:Id. ∀S:Id List. ∀G:Graph(S). ∀k:Knd.
  (↑graph-rcvset(a;b;S;G;k) ⇐⇒ ∃i,j:Id. ((i ∈ S) ∧ (j ∈ S) ∧ (i⟶j)∈G ∧ (k rcv((link(a j) from to j),b) ∈ Knd)))

Definition: graph-rcvs
graph-rcvs(S;G;a;b;j) ==  mapfilter(λi.rcv((link(a j) from to j),b);λi.j ∈b i;S)

Lemma: graph-rcvs_wf
[S:Id List]. ∀[G:Graph(S)]. ∀[a:Id ⟶ Id ⟶ Id]. ∀[b:Id]. ∀[j:{j:Id| (j ∈ S)} ].  (graph-rcvs(S;G;a;b;j) ∈ Knd List)

Lemma: member-graph-rcvs
S:Id List. ∀G:Graph(S). ∀a:Id ⟶ Id ⟶ Id. ∀b:Id. ∀j:{j:Id| (j ∈ S)} . ∀k:Knd.
  ((k ∈ graph-rcvs(S;G;a;b;j)) ⇐⇒ ∃i:Id. ((i ∈ S) ∧ (i⟶j)∈G ∧ (k rcv((link(a j) from to j),b) ∈ Knd)))

Lemma: locl_rcv_lemma
tg,l,a:Top.  (locl(a) rcv(l,tg) ff)

Lemma: rcv_locl_lemma
a,tg,l:Top.  (rcv(l,tg) locl(a) ff)

Lemma: locl_locl_lemma
b,a:Top.  (locl(a) locl(b) b)

Lemma: rcv_rcv_lemma
t',l',t,l:Top.  (rcv(l,t) rcv(l',t') l' ∧b t')

Lemma: map-concat-filter-lemma1
[A,B:Type]. ∀[L2:(tg:Id × (A ⟶ B ⟶ (Top List))) List]. ∀[L:(Top × Id × Top) List]. ∀[tg:Id]. ∀[a:A]. ∀[b:B].
  {(filter(λms.fst(snd(ms)) tg;L) [] ∈ ((Top × Id × Top) List)) supposing 
      ((¬(tg ∈ map(λp.(fst(p));L2))) and 
      (map(λx.(snd(x));L) concat(map(λtgf.map(λx.<fst(tgf), x>;(snd(tgf)) b);L2)) ∈ ((tg:Id × Top) List)))}

Lemma: map-concat-filter-lemma2
[C:Id ⟶ Type]. ∀[A,B:Type]. ∀[L2:(tg:Id × (A ⟶ B ⟶ (C[tg] List))) List]. ∀[L:(l:IdLnk × t:Id × C[t]) List].
[tg:Id]. ∀[a:A]. ∀[b:B].
  {(||filter(λms.fst(snd(ms)) tg;L)|| 0 ∈ ℤsupposing 
      ((¬(tg ∈ map(λp.(fst(p));L2))) and 
      (map(λx.(snd(x));L) concat(map(λtgf.map(λx.<fst(tgf), x>;(snd(tgf)) b);L2)) ∈ ((tg:Id × C[tg]) List)))}

Definition: standard-ds
StandardDS ==  <λa.if (a =z 2) then IdLnk else Id fi , λa.if (a =z 2) then IdLnkDeq else IdDeq fi >

Lemma: standard-ds_wf
StandardDS ∈ DS({1..6-})

Definition: has-src
has-src(i;k) ==  isrcv(k) ∧b source(lnk(k)) i

Lemma: has-src_wf
[i:Id]. ∀[k:Knd].  (has-src(i;k) ∈ 𝔹)

Lemma: assert-has-src
[i:Id]. ∀[k:Knd].  uiff(↑has-src(i;k);(↑isrcv(k)) c∧ (source(lnk(k)) i ∈ Id))

Definition: hasloc
hasloc(k;i) ==  ¬b(isrcv(k) ∧b bdestination(lnk(k)) i))

Lemma: hasloc_wf
[i:Id]. ∀[k:Knd].  (hasloc(k;i) ∈ 𝔹)

Lemma: assert-hasloc
[i:Id]. ∀[k:Knd].  uiff(↑hasloc(k;i);destination(lnk(k)) i ∈ Id supposing ↑isrcv(k))

Lemma: graph-rcvs_wf2
[S:Id List]. ∀[G:Graph(S)]. ∀[a:Id ⟶ Id ⟶ Id]. ∀[b:Id]. ∀[j:{j:Id| (j ∈ S)} ].
  (graph-rcvs(S;G;a;b;j) ∈ {k:Knd| ↑hasloc(k;j)}  List)

Lemma: subtype-set-hasloc
[i:Id]. ∀[d:{k:Knd| ↑hasloc(k;i)}  List].  ({k:Knd| (k ∈ d)}  ⊆{k:{k:Knd| ↑hasloc(k;i)} (k ∈ d)} )

Definition: kind-loc
kind-loc(k;i) ==  islocal(k) ∨bdestination(lnk(k)) i

Lemma: kind-loc_wf
[k:Knd]. ∀[i:Id].  (kind-loc(k;i) ∈ 𝔹)

Definition: LocKnd
LocKnd ==  {ik:Id × Knd| let i,k ik in ↑hasloc(k;i)} 

Lemma: LocKnd_wf
LocKnd ∈ Type

Definition: locknd-deq
locknd-deq() ==  product-deq(Id;Knd;IdDeq;KindDeq)

Lemma: locknd-deq_wf
locknd-deq() ∈ EqDecider(LocKnd)

Definition: locknd-spread
let i,k:LocKnd ik in P[i; k] ==  let i,k ik in P[i; k]

Lemma: locknd-spread_wf
[T:i:Id ⟶ k:{k:Knd| ↑hasloc(k;i)}  ⟶ Type]. ∀[P:i:Id ⟶ k:{k:Knd| ↑hasloc(k;i)}  ⟶ T[i;k]]. ∀[ik:LocKnd].
  (let i,k:LocKnd ik in P[i;k] ∈ T[fst(ik);snd(ik)])

Lemma: locknd-spread_wf2
[T:Type]. ∀[P:i:Id ⟶ k:{k:Knd| ↑hasloc(k;i)}  ⟶ T]. ∀[ik:LocKnd].  (let i,k:LocKnd ik in P[i;k] ∈ T)

Definition: locknd
locknd(i;k) ==  kindcase(k;a.<i, k>;l,tg.<destination(l), k>)

Lemma: locknd_wf
[i:Id]. ∀[k:Knd].  (locknd(i;k) ∈ LocKnd)

Lemma: locknd_functionality_isrcv
[i,j:Id]. ∀[k1,k2:Knd].  (locknd(i;k1) locknd(j;k2) ∈ LocKnd) supposing ((k1 k2 ∈ Knd) and (↑isrcv(k1)))

Definition: MaName
MaName ==  LocKnd (Id × Id)

Lemma: MaName_wf
MaName ∈ Type

Definition: varname
varname(x;i) ==  inr <i, x> 

Lemma: varname_wf
[x,i:Id].  (varname(x;i) ∈ MaName)

Definition: kindname
kindname(i;k) ==  inl <i, k>

Lemma: kindname_wf
[i:Id]. ∀[k:{k:Knd| ↑hasloc(k;i)} ].  (kindname(i;k) ∈ MaName)

Definition: maname-deq
maname-deq() ==  union-deq(LocKnd;Id × Id;locknd-deq();product-deq(Id;Id;IdDeq;IdDeq))

Lemma: maname-deq_wf
maname-deq() ∈ EqDecider(MaName)

Lemma: decidable__equal_MaName
x,y:MaName.  Dec(x y ∈ MaName)

Definition: name-case
name-case(n;i,k.A[i; k];j,x.B[j; x]) ==
  case of inl(ik) => let i,k:LocKnd ik in A[i; k] inr(p) => let j,x in B[j; x]

Lemma: name-case_wf
[T:Type]. ∀[A:i:Id ⟶ {k:Knd| ↑hasloc(k;i)}  ⟶ T]. ∀[B:Id ⟶ Id ⟶ T]. ∀[n:MaName].
  (name-case(n;i,k.A[i;k];j,x.B[j;x]) ∈ T)

Lemma: decidable__l_disjoint_manames
nms1,nms2:MaName List.  Dec(l_disjoint(MaName;nms1;nms2))

Definition: manames-overlap-case
if nms1 and nms2 overlap then else fi ==  if p:l_disjoint(MaName;nms1;nms2) then else fi 

Lemma: manames-overlap-case_wf
[T:Type]. ∀[x,y:T]. ∀[nms1,nms2:MaName List].  (if nms1 and nms2 overlap then else fi ∈ T)

Lemma: manames-overlap-case-symmetry
[x,y:Top]. ∀[nms1,nms2:MaName List].
  (if nms1 and nms2 overlap then else fi if nms2 and nms1 overlap then else fi)

Lemma: manames-overlap-nil
[x,y:Top]. ∀[nms:MaName List].  (if [] and nms overlap then else fi y)

Lemma: manames-overlap-nil2
[x,y:Top]. ∀[nms:MaName List].  (if nms and [] overlap then else fi y)

Lemma: kind-member-normal-form
[k,L:Top].
  (rec-case(L) of
   [] => ff
   a::_ =>
    r.case a
    of inl(pa) =>
    case k
     of inl(qa) =>
     let x,y pa 
     in let x1,y1 
        in if x1=2 let x,y qa 
                   in let x,y 
                      in x
            then let x2,y2 y1 
                 in if x2=2 let x,y qa 
                            in let x,y 
                               in let x,y 
                                  in x
                     then if y2=2 let x,y qa 
                                  in let x,y 
                                     in let x,y 
                                        in y
                           then if y=2 let x,y qa 
                                       in y
                                 then inl Ax
                                 else r
                           else r
                     else r
            else r
     inr(_) =>
     r
    inr(pb) =>
    case of inl(_) => inr(qb) => if pb=2 qb then tt else k ∈b L)

Lemma: id-member-normal-form
[x,L:Top].  (rec-case(L) of [] => ff a::_ => r.if a=2 then tt else x ∈b L)

Lemma: filter-normal-form
[P,L:Top].  (rec-case(L) of [] => [] a::_ => r.if P[a] then [a r] else fi  filter(λa.P[a];L))

Lemma: remove-repeats-normal-form
[eq,L:Top].
  (rec-case(L) of
   [] => []
   a::_ =>
    r.[a rec-case(r) of [] => [] a@0::_ => r.if eq a@0 then else [a@0 r] fi remove-repeats(eq;L))

Lemma: append-normal-form
[A,B:Top].  (rec-case(A) of [] => a::_ => r.[a r] B)

Lemma: length-normal-form
[A:Top]. (rec-case(A) of [] => _::as' => _.||as'|| ||A||)

Definition: urand
urand(n;a) ==  random(uniform-fps(n);a;a)

Lemma: urand_wf
[n:ℕ+]. ∀[a:Id].  (urand(n;a) ∈ ℕ ⟶ ℕn)

Definition: fpf
a:A fp-> B[a] ==  d:A List × (a:{a:A| (a ∈ d)}  ⟶ B[a])

Lemma: fpf_wf
[A:Type]. ∀[B:A ⟶ Type].  (a:A fp-> B[a] ∈ Type)

Lemma: subtype-fpf-general
[A:Type]. ∀[P:A ⟶ ℙ]. ∀[B:A ⟶ 𝕌{j}].  (a:{a:A| P[a]}  fp-> B[a] ⊆a:A fp-> B[a])

Lemma: subtype-fpf
[A:Type]. ∀[P:A ⟶ ℙ]. ∀[B:A ⟶ Type].  (a:{a:A| P[a]}  fp-> B[a] ⊆a:A fp-> B[a])

Lemma: subtype-fpf-variant
[A:Type]. ∀[P:A ⟶ ℙ]. ∀[B:A ⟶ 𝕌'].  (a:{a:A| P[a]}  fp-> B[a] ⊆a:A fp-> B[a])

Lemma: subtype-fpf2
[A:Type]. ∀[B1,B2:A ⟶ Type].  a:A fp-> B1[a] ⊆a:A fp-> B2[a] supposing ∀a:A. (B1[a] ⊆B2[a])

Lemma: subtype-fpf3
[A1,A2:Type]. ∀[B1:A1 ⟶ Type]. ∀[B2:A2 ⟶ Type].
  (a:A1 fp-> B1[a] ⊆a:A2 fp-> B2[a]) supposing ((∀a:A1. (B1[a] ⊆B2[a])) and strong-subtype(A1;A2))

Lemma: subtype-fpf-void
[A:Type]. ∀[B1:Top]. ∀[B2:A ⟶ Type].  (a:Void fp-> B1[a] ⊆a:A fp-> B2[a])

Definition: fpf-dom
x ∈ dom(f) ==  x ∈b fst(f)

Lemma: fpf-dom_wf
[A:Type]. ∀[eq:EqDecider(A)]. ∀[f:a:A fp-> Top]. ∀[x:A].  (x ∈ dom(f) ∈ 𝔹)

Definition: fpf-domain
fpf-domain(f) ==  fst(f)

Lemma: fpf-domain_wf2
[A,B:Type]. ∀[f:a:A fp-> B].  (fpf-domain(f) ∈ List)

Lemma: fpf-domain_wf
[A:Type]. ∀[f:a:A fp-> Top].  (fpf-domain(f) ∈ List)

Lemma: member-fpf-domain
[A:Type]. ∀f:a:A fp-> Top. ∀eq:EqDecider(A). ∀x:A.  (↑x ∈ dom(f) ⇐⇒ (x ∈ fpf-domain(f)))

Lemma: member-fpf-domain-variant
[A,V:Type].  ∀f:a:A fp-> V × Top. ∀eq:EqDecider(A). ∀x:A.  (↑x ∈ dom(f) ⇐⇒ (x ∈ fpf-domain(f)))

Lemma: fpf-trivial-subtype-set
[A:Type]. ∀[P:A ⟶ ℙ]. ∀[f:a:{a:A| P[a]}  fp-> Type × Top].  (f ∈ a:A fp-> Type × Top)

Lemma: fpf-trivial-subtype-top
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]].  (f ∈ a:A fp-> Top)

Lemma: fpf-type
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]].  (f ∈ a:{a:A| (a ∈ fpf-domain(f))}  fp-> B[a])

Lemma: fpf-dom_functionality
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq1,eq2:EqDecider(A)]. ∀[f:a:A fp-> B[a]]. ∀[x:A].  x ∈ dom(f) x ∈ dom(f)

Lemma: fpf-dom_functionality2
[A:Type]. ∀[eq1,eq2:EqDecider(A)]. ∀[f:a:A fp-> Top]. ∀[x:A].  {↑x ∈ dom(f) supposing ↑x ∈ dom(f)}

Lemma: fpf-dom-type
[X,Y:Type]. ∀[eq:EqDecider(Y)]. ∀[f:x:X fp-> Top]. ∀[x:Y].  (x ∈ X) supposing ((↑x ∈ dom(f)) and strong-subtype(X;Y))

Lemma: fpf-dom-type2
[X,Y:Type]. ∀[eq:EqDecider(Y)]. ∀[f:x:X fp-> Top]. ∀[x:Y].  {x ∈ supposing ↑x ∈ dom(f)} supposing strong-subtype(X;Y)

Definition: fpf-empty
⊗ ==  <[], λx.⋅>

Lemma: fpf-empty_wf
[A:Type]. ∀[B:A ⟶ Type].  (⊗ ∈ x:A fp-> B[x])

Definition: fpf-is-empty
fpf-is-empty(f) ==  (||fst(f)|| =z 0)

Lemma: fpf-is-empty_wf
[A:Type]. ∀[f:x:A fp-> Top].  (fpf-is-empty(f) ∈ 𝔹)

Lemma: assert-fpf-is-empty
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:x:A fp-> B[x]].  uiff(↑fpf-is-empty(f);f = ⊗ ∈ x:A fp-> B[x])

Lemma: fpf-null-domain
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:Void ⟶ Top].  (<[], f> = ⊗ ∈ x:A fp-> B[x])

Definition: fpf-ap
f(x) ==  (snd(f)) x

Lemma: fpf-ap_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[eq:EqDecider(A)]. ∀[x:A].  f(x) ∈ B[x] supposing ↑x ∈ dom(f)

Lemma: fpf_ap_pair_lemma
x,eq,f,d:Top.  (<d, f>(x) x)

Lemma: fpf-ap_functionality
[eq1,eq2,f,x:Top].  (f(x) f(x))

Definition: fpf-cap
f(x)?z ==  if x ∈ dom(f) then f(x) else fi 

Lemma: fpf-cap-wf-univ
[A:Type]. ∀[f:a:A fp-> Type]. ∀[eq:EqDecider(A)]. ∀[x:A]. ∀[z:Type].  (f(x)?z ∈ Type)

Lemma: fpf-cap_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[eq:EqDecider(A)]. ∀[x:A]. ∀[z:B[x]].  (f(x)?z ∈ B[x])

Lemma: alist-domain-first
[A:Type]
  ∀d:A List. ∀f1:a:{a:A| (a ∈ d)}  ⟶ Top. ∀x:A. ∀eq:EqDecider(A).
    ((x ∈ d)
     (∃i:ℕ||d||. ((∀j:ℕi. ((fst(map(λx.<x, f1 x>;d)[j])) x ∈ A))) ∧ ((fst(map(λx.<x, f1 x>;d)[i])) x ∈ A))))

Lemma: fpf-as-apply-alist
[A,B:Type]. ∀[f:a:A fp-> B]. ∀[eq:EqDecider(A)].
  (f = <fpf-domain(f), λx.outl(apply-alist(eq;map(λx.<x, f(x)>;fpf-domain(f));x))> ∈ a:A fp-> B)

Definition: fpf-union
fpf-union(f;g;eq;R;x) ==  if x ∈ dom(f) ∧b x ∈ dom(g) then f(x) filter(R f(x);g(x)) else f(x)?g(x)?[] fi 

Lemma: fpf-union_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:x:A fp-> B[x] List]. ∀[x:A]. ∀[R:⋂a:A. ((B[a] List) ⟶ B[a] ⟶ 𝔹)].
  (fpf-union(f;g;eq;R;x) ∈ B[x] List)

Lemma: fpf-union-contains
[A:Type]. ∀[B:A ⟶ Type].
  ∀eq:EqDecider(A). ∀f,g:x:A fp-> B[x] List. ∀x:A. ∀R:⋂a:A. ((B[a] List) ⟶ B[a] ⟶ 𝔹).  f(x)?[] ⊆ fpf-union(f;g;eq;R;x)

Definition: fpf-union-compatible
fpf-union-compatible(A;C;x.B[x];eq;R;f;g) ==
  ∀x:A
    ((↑x ∈ dom(g))
     (↑x ∈ dom(f))
     (∀a:C
          ((((a ∈ g(x)) ∧ (¬↑(R f(x) a))) ∨ ((a ∈ f(x)) ∧ (¬↑(R g(x) a))))
           (∃a':B[x]. ((a' a ∈ C) ∧ (a' ∈ f(x)) ∧ (a' ∈ g(x)))))))

Lemma: fpf-union-compatible_wf
[A,C:Type]. ∀[B:A ⟶ Type].
  ∀[eq:EqDecider(A)]. ∀[f,g:x:A fp-> B[x] List]. ∀[R:(C List) ⟶ C ⟶ 𝔹].
    (fpf-union-compatible(A;C;x.B[x];eq;R;f;g) ∈ ℙ
  supposing ∀x:A. (B[x] ⊆C)

Lemma: fpf-union-compatible_symmetry
[A:Type]. ∀[B:A ⟶ Type]. ∀[C:Type].
  ∀eq:EqDecider(A). ∀f,g:x:A fp-> B[x] List. ∀R:(C List) ⟶ C ⟶ 𝔹.
    (fpf-union-compatible(A;C;x.B[x];eq;R;f;g)  fpf-union-compatible(A;C;x.B[x];eq;R;g;f)) 
  supposing ∀a:A. (B[a] ⊆C)

Lemma: fpf-union-compatible-subtype
[A,C:Type]. ∀[B1,B2:A ⟶ Type].
  (∀eq:EqDecider(A). ∀f,g:x:A fp-> B1[x] List. ∀R:(C List) ⟶ C ⟶ 𝔹.
     (fpf-union-compatible(A;C;x.B1[x];eq;R;f;g)  fpf-union-compatible(A;C;x.B2[x];eq;R;f;g))) supposing 
     ((∀x:A. (B1[x] ⊆B2[x])) and 
     (∀a:A. (B2[a] ⊆C)))

Lemma: fpf-union-compatible-self
[A,C:Type]. ∀[B:A ⟶ Type].
  ∀eq:EqDecider(A). ∀f:x:A fp-> B[x] List. ∀R:(C List) ⟶ C ⟶ 𝔹.  fpf-union-compatible(A;C;x.B[x];eq;R;f;f) 
  supposing ∀a:A. (B[a] ⊆C)

Definition: fpf-single-valued
fpf-single-valued(A;eq;x.B[x];V;g) ==
  ∀x:A. ((↑x ∈ dom(g))  (∀b1,b2:B[x].  ((b1 ∈ g(x))  (b2 ∈ g(x))  (b1 b2 ∈ V)  (b1 b2 ∈ B[x]))))

Lemma: fpf-single-valued_wf
[A,V:Type]. ∀[B:A ⟶ Type].
  ∀[eq:EqDecider(A)]. ∀[g:x:A fp-> B[x] List].  (fpf-single-valued(A;eq;x.B[x];V;g) ∈ ℙsupposing ∀a:A. (B[a] ⊆V)

Lemma: fpf-union-contains2
[A,V:Type]. ∀[B:A ⟶ Type].
  ∀eq:EqDecider(A). ∀f,g:x:A fp-> B[x] List.
    ∀x:A. ∀R:(V List) ⟶ V ⟶ 𝔹.  (fpf-union-compatible(A;V;x.B[x];eq;R;f;g)  g(x)?[] ⊆ fpf-union(f;g;eq;R;x)) 
    supposing fpf-single-valued(A;eq;x.B[x];V;g) 
  supposing ∀a:A. (B[a] ⊆V)

Definition: fpf-val
!= f(x) ==> P[a; z] ==  (↑x ∈ dom(f))  P[x; f(x)]

Lemma: fpf-val_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[eq:EqDecider(A)]. ∀[x:A]. ∀[P:a:{a:A| ↑a ∈ dom(f)}  ⟶ B[a] ⟶ ℙ].
  (z != f(x) ==> P[x;z] ∈ ℙ)

Definition: fpf-sub
f ⊆ ==  ∀x:A. ((↑x ∈ dom(f))  ((↑x ∈ dom(g)) c∧ (f(x) g(x) ∈ B[x])))

Lemma: fpf-sub_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]].  (f ⊆ g ∈ ℙ)

Lemma: fpf-sub_witness
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]].  (f ⊆  x,y. <Ax, Ax> ∈ f ⊆ g))

Lemma: fpf-sub-set
[A:Type]. ∀[P:A ⟶ ℙ]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:{a:A| P[a]}  fp-> B[a]].  f ⊆ supposing f ⊆ g

Lemma: sq_stable__fpf-sub
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]].  SqStable(f ⊆ g)

Lemma: fpf-empty-sub
[A:Type]. ∀[B,eq,g:Top].  ⊗ ⊆ g

Lemma: fpf-sub-functionality
[A,A':Type].
  ∀[B:A ⟶ Type]. ∀[C:A' ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[eq':EqDecider(A')]. ∀[f,g:a:A fp-> B[a]].
    (f ⊆ g) supposing (f ⊆ and (∀a:A. (B[a] ⊆C[a]))) 
  supposing strong-subtype(A;A')

Lemma: fpf-sub-functionality2
[A,A':Type].
  ∀[B:A ⟶ Type]. ∀[C:A' ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[eq':EqDecider(A')]. ∀[f,g:a:A fp-> B[a]].
    (f ⊆ g) supposing (f ⊆ and (∀a:A. (B[a] ⊆C[a]))) 
  supposing strong-subtype(A;A')

Lemma: fpf-sub_functionality
[A,A':Type].
  ∀[B:A ⟶ Type]. ∀[C:A' ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[eq':EqDecider(A')]. ∀[f,g:a:A fp-> B[a]].
    {f ⊆ supposing f ⊆ g} supposing ∀a:A. (B[a] ⊆C[a]) 
  supposing strong-subtype(A;A')

Lemma: fpf-sub_functionality2
[A,A':Type].
  ∀[B:A ⟶ Type]. ∀[C:A' ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[eq':EqDecider(A')]. ∀[f,g:a:A fp-> B[a]].
    {f ⊆ supposing f ⊆ g} supposing ∀a:A. (B[a] ⊆C[a]) 
  supposing strong-subtype(A;A')

Lemma: fpf-sub_transitivity
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g,h:a:A fp-> B[a]].  (f ⊆ h) supposing (g ⊆ and f ⊆ g)

Lemma: fpf-sub_weakening
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]].  f ⊆ supposing g ∈ a:A fp-> B[a]

Definition: fpf-contains
f ⊆⊆ ==  ∀x:A. ((↑x ∈ dom(f))  ((↑x ∈ dom(g)) c∧ f(x) ⊆ g(x)))

Lemma: fpf-contains_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a] List].  (f ⊆⊆ g ∈ ℙ)

Lemma: fpf-contains_self
[A:Type]. ∀[B:A ⟶ Type].  ∀eq:EqDecider(A). ∀f:a:A fp-> B[a] List.  f ⊆⊆ f

Lemma: subtype-fpf-cap
[X:Type]. ∀[eq:EqDecider(X)]. ∀[f,g:x:X fp-> Type].  {∀[x:X]. (f(x)?Top ⊆g(x)?Top)} supposing g ⊆ f

Lemma: subtype-fpf-cap-top
[T,X:Type]. ∀[eq:EqDecider(X)]. ∀[f,g:x:X fp-> Type]. ∀[x:X].  f(x)?T ⊆g(x)?Top supposing g ⊆ f

Lemma: subtype-fpf-cap-top2
[X,T:Type]. ∀[eq:EqDecider(X)]. ∀[g:x:X fp-> Type]. ∀[x:X].  T ⊆g(x)?Top supposing (↑x ∈ dom(g))  (T ⊆g(x))

Lemma: fpf-cap-void-subtype
[A:Type]. ∀[eq:EqDecider(A)]. ∀[ds:x:A fp-> Type]. ∀[x:A].  (ds(x)?Void ⊆ds(x)?Top)

Lemma: subtype-fpf-cap-void
[T,X:Type]. ∀[eq:EqDecider(X)]. ∀[f,g:x:X fp-> Type]. ∀[x:X].  f(x)?Void ⊆g(x)?T supposing f ⊆ g

Lemma: fpf-cap_functionality
[A:Type]. ∀[d1,d2:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[x:A]. ∀[z:B[x]].  (f(x)?z f(x)?z ∈ B[x])

Lemma: fpf-cap-subtype_functionality
[A:Type]. ∀[d1,d2:EqDecider(A)]. ∀[f:a:A fp-> Type]. ∀[x:A]. ∀[z:Type].  (f(x)?z ⊆f(x)?z)

Lemma: fpf-cap_functionality_wrt_sub
[A:Type]. ∀[d1,d2,d3,d4:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g:a:A fp-> B[a]]. ∀[x:A]. ∀[z:B[x]].
  (f(x)?z g(x)?z ∈ B[x]) supposing ((↑x ∈ dom(f)) and f ⊆ g)

Lemma: fpf-cap-subtype_functionality_wrt_sub
[A:Type]. ∀[d1,d2,d4:EqDecider(A)]. ∀[f,g:a:A fp-> Type]. ∀[x:A].  {g(x)?Top ⊆f(x)?Top supposing f ⊆ g}

Lemma: fpf-cap-subtype_functionality_wrt_sub2
[A1,A2,A3:Type]. ∀[d,d':EqDecider(A3)]. ∀[d2:EqDecider(A2)]. ∀[f:a:A1 fp-> Type]. ∀[g:a:A2 fp-> Type]. ∀[x:A3].
  ({g(x)?Top ⊆f(x)?Top supposing f ⊆ g}) supposing (strong-subtype(A2;A3) and strong-subtype(A1;A2))

Definition: fpf-compatible
|| ==  ∀x:A. (((↑x ∈ dom(f)) ∧ (↑x ∈ dom(g)))  (f(x) g(x) ∈ B[x]))

Lemma: fpf-compatible_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]].  (f || g ∈ ℙ)

Lemma: fpf-compatible-wf2
[A:Type]. ∀[B,C:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f:a:A fp-> B[a]]. ∀[g:a:A fp-> C[a]].
  || g ∈ ℙ supposing ∀x:A. ((↑x ∈ dom(f))  (↑x ∈ dom(g))  (B[x] ⊆C[x]))

Lemma: fpf-compatible_monotonic
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f1,g1,f2,g2:a:A fp-> B[a]].
  (f1 || g1) supposing (f2 || g2 and g1 ⊆ g2 and f1 ⊆ f2)

Lemma: fpf-compatible_monotonic-guard
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f1,g1,f2,g2:a:A fp-> B[a]].
  ({f1 || g1 supposing f2 || g2}) supposing (g1 ⊆ g2 and f1 ⊆ f2)

Definition: fpf-compatible-mod
fpf-compatible-mod(A;a.B[a];eq;
R;f;g) ==
  ∀x:A. (((↑x ∈ dom(f)) ∧ (↑x ∈ dom(g)))  (¬↑(R f(x) g(x)))  (f(x) g(x) ∈ B[x]))

Lemma: fpf-compatible-mod_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]]. ∀[R:⋂a:A. (B[a] ⟶ B[a] ⟶ 𝔹)].
  (fpf-compatible-mod(A;a.B[a];eq;
   R;f;g) ∈ ℙ)

Lemma: fpf-sub-compatible-left
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]].  || supposing f ⊆ g

Lemma: fpf-sub-compatible-right
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]].  || supposing g ⊆ f

Lemma: subtype-fpf-cap5
[X:Type]. ∀[eq:EqDecider(X)]. ∀[f,g:x:X fp-> Type]. ∀[x:X].  f(x)?Void ⊆g(x)?Top supposing || g

Lemma: subtype-fpf-cap-void2
[X:Type]. ∀[eq:EqDecider(X)]. ∀[f,g:x:X fp-> Type]. ∀[x:X]. ∀[z:g(x)?Void].  f(x)?Void ⊆g(x)?Void supposing || g

Lemma: subtype-fpf-cap-void-list
[X:Type]. ∀[eq:EqDecider(X)]. ∀[f,g:x:X fp-> Type]. ∀[x:X].  (f(x)?Void List) ⊆(g(x)?Void List) supposing f ⊆ g

Lemma: fpf-cap-compatible
[X:Type]. ∀[eq:EqDecider(X)]. ∀[f,g:x:X fp-> Type]. ∀[x:X].
  (f(x)?Void g(x)?Void ∈ Type) supposing (g(x)?Void and f(x)?Void and || g)

Definition: fpf-join
f ⊕ ==  <(fst(f)) filter(λa.(¬ba ∈ dom(f));fst(g)), λa.f(a)?g(a)>

Lemma: fpf-join_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[f,g:a:A fp-> B[a]]. ∀[eq:EqDecider(A)].  (f ⊕ g ∈ a:A fp-> B[a])

Lemma: fpf-join-wf
[A:Type]. ∀[B,C,D:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[g:a:A fp-> C[a]]. ∀[eq:EqDecider(A)].
  (f ⊕ g ∈ a:A fp-> D[a]) supposing 
     ((∀a:A. ((↑a ∈ dom(g))  (C[a] ⊆D[a]))) and 
     (∀a:A. ((↑a ∈ dom(f))  (B[a] ⊆D[a]))))

Lemma: fpf-join-empty
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[eq:EqDecider(A)].  (⊗ ⊕ f ∈ a:A fp-> B[a])

Lemma: fpf-empty-join
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[eq:EqDecider(A)].  (f ⊕ ⊗ f ∈ a:A fp-> B[a])

Lemma: fpf-join-empty-sq
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[eq:EqDecider(A)].  (⊗ ⊕ ~ <fst(f), λa.((snd(f)) a)>)

Lemma: fpf-join-idempotent
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[eq:EqDecider(A)].  (f ⊕ f ∈ a:A fp-> B[a])

Lemma: fpf-join-assoc
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g,h:a:A fp-> B[a]].  (f ⊕ g ⊕ f ⊕ g ⊕ h ∈ a:A fp-> B[a])

Lemma: fpf-join-dom
[A:Type]. ∀[B:A ⟶ Type].
  ∀eq:EqDecider(A). ∀f,g:a:A fp-> B[a]. ∀x:A.  (↑x ∈ dom(f ⊕ g) ⇐⇒ (↑x ∈ dom(f)) ∨ (↑x ∈ dom(g)))

Lemma: fpf-join-dom2
[A:Type]. ∀eq:EqDecider(A). ∀f,g:a:A fp-> Top. ∀x:A.  (↑x ∈ dom(f ⊕ g) ⇐⇒ (↑x ∈ dom(f)) ∨ (↑x ∈ dom(g)))

Lemma: fpf-join-dom-sq
[A:Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> Top]. ∀[x:A].  (x ∈ dom(f ⊕ g) x ∈ dom(f) ∨bx ∈ dom(g))

Lemma: fpf-domain-join
[A:Type]
  ∀f,g:a:A fp-> Top. ∀eq:EqDecider(A). ∀x:A.  ((x ∈ fpf-domain(f ⊕ g)) ⇐⇒ (x ∈ fpf-domain(f)) ∨ (x ∈ fpf-domain(g)))

Lemma: fpf-join-domain
[A:Type]. ∀f,g:a:A fp-> Top. ∀eq:EqDecider(A).  fpf-domain(f ⊕ g) ⊆ fpf-domain(f) fpf-domain(g)

Lemma: fpf-join-is-empty
[A:Type]. ∀[eq:EqDecider(A)]. ∀[f,g:x:A fp-> Top].  (fpf-is-empty(f ⊕ g) fpf-is-empty(f) ∧b fpf-is-empty(g))

Lemma: fpf-join-ap
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]]. ∀[x:A].
  f ⊕ g(x) if x ∈ dom(f) then f(x) else g(x) fi  ∈ B[x] supposing ↑x ∈ dom(f ⊕ g)

Lemma: fpf-join-ap-left
[A:Type]. ∀[B,C:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f:a:A fp-> B[a]]. ∀[g:a:A fp-> C[a]]. ∀[x:A].
  f ⊕ g(x) f(x) ∈ B[x] supposing ↑x ∈ dom(f)

Lemma: fpf-join-ap-sq
[A:Type]. ∀[eq:EqDecider(A)]. ∀[f:a:A fp-> Top]. ∀[g:Top]. ∀[x:A].  (f ⊕ g(x) if x ∈ dom(f) then f(x) else g(x) fi )

Lemma: fpf-join-cap-sq
[A:Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> Top]. ∀[x:A]. ∀[z:Top].
  (f ⊕ g(x)?z if x ∈ dom(f) then f(x)?z else g(x)?z fi )

Lemma: fpf-join-cap
[A:Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> Top]. ∀[x:A]. ∀[z:Top].  (f ⊕ g(x)?z f(x)?g(x)?z)

Lemma: fpf-join-range
[A:Type]. ∀[eq:EqDecider(A)]. ∀[df:x:A fp-> Type]. ∀[f:x:A fp-> df(x)?Top]. ∀[dg:x:A fp-> Type].
[g:x:A fp-> dg(x)?Top].
  (f ⊕ g ∈ x:A fp-> df ⊕ dg(x)?Top) supposing 
     ((∀x:A. ((↑x ∈ dom(g))  (↑x ∈ dom(dg)))) and 
     (∀x:A. ((↑x ∈ dom(f))  (↑x ∈ dom(df)))) and 
     df || dg)

Lemma: fpf-sub-join-left
[A:Type]. ∀[B1,B2:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f:a:A fp-> B1[a]]. ∀[g:a:A fp-> Top].  f ⊆ f ⊕ g

Lemma: fpf-sub-join-left2
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,h,g:a:A fp-> B[a]].  h ⊆ f ⊕ supposing h ⊆ f

Lemma: fpf-sub-join-right
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]].  g ⊆ f ⊕ supposing || g

Lemma: fpf-sub-join-right2
[A:Type]. ∀[B,C:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f:a:A fp-> B[a]]. ∀[g:a:A fp-> C[a]].
  g ⊆ f ⊕ supposing ∀x:A. (((↑x ∈ dom(f)) ∧ (↑x ∈ dom(g)))  ((B[x] ⊆C[x]) c∧ (f(x) g(x) ∈ C[x])))

Lemma: fpf-sub-join
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]].  {f ⊆ f ⊕ g ∧ g ⊆ f ⊕ g} supposing || g

Lemma: fpf-join-sub
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f1,g1,f2,g2:a:A fp-> B[a]].
  (f1 ⊕ f2 ⊆ g1 ⊕ g2) supposing (f2 ⊆ g2 and f1 ⊆ g1 and f2 || g1)

Lemma: fpf-join-sub2
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f1,g,f2:a:A fp-> B[a]].  (f1 ⊕ f2 ⊆ g) supposing (f2 ⊆ and f1 ⊆ g)

Definition: fpf-join-list
(L) ==  reduce(λf,g. f ⊕ g;⊗;L)

Lemma: fpf-join-list_wf
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[L:a:A fp-> B[a] List].  (⊕(L) ∈ a:A fp-> B[a])

Lemma: fpf-join-list-dom
[A:Type]. ∀eq:EqDecider(A). ∀[B:A ⟶ Type]. ∀L:a:A fp-> B[a] List. ∀x:A.  (↑x ∈ dom(⊕(L)) ⇐⇒ (∃f∈L. ↑x ∈ dom(f)))

Lemma: fpf-join-list-dom2
[A:Type]. ∀eq:EqDecider(A). ∀L:a:A fp-> Top List. ∀x:A.  (↑x ∈ dom(⊕(L)) ⇐⇒ (∃f∈L. ↑x ∈ dom(f)))

Lemma: fpf-join-list-domain
[A:Type]
  ∀eq:EqDecider(A)
    ∀[B:A ⟶ Type]. ∀L:a:A fp-> B[a] List. ∀x:A.  ((x ∈ fpf-domain(⊕(L))) ⇐⇒ (∃f∈L. (x ∈ fpf-domain(f))))

Lemma: fpf-join-list-domain2
[A:Type]. ∀eq:EqDecider(A). ∀L:a:A fp-> Top List. ∀x:A.  ((x ∈ fpf-domain(⊕(L))) ⇐⇒ (∃f∈L. (x ∈ fpf-domain(f))))

Lemma: fpf-join-list-ap
[A:Type]
  ∀eq:EqDecider(A)
    ∀[B:A ⟶ Type]
      ∀L:a:A fp-> B[a] List. ∀x:A.  (∃f∈L. (↑x ∈ dom(f)) ∧ (⊕(L)(x) f(x) ∈ B[x])) supposing ↑x ∈ dom(⊕(L))

Lemma: fpf-join-list-ap2
[A:Type]
  ∀eq:EqDecider(A)
    ∀[B:A ⟶ Type]
      ∀L:a:A fp-> B[a] List. ∀x:A.  ((x ∈ fpf-domain(⊕(L)))  (∃f∈L. (↑x ∈ dom(f)) ∧ (⊕(L)(x) f(x) ∈ B[x])))

Lemma: fpf-join-list-ap-disjoint
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[L:a:A fp-> B[a] List]. ∀[x:A].
  (∀[f:a:A fp-> B[a]]. (⊕(L)(x) f(x) ∈ B[x]) supposing ((↑x ∈ dom(f)) and (f ∈ L))) supposing 
     ((∀f,g∈L.  ∀x:A. ((↑x ∈ dom(f)) ∧ (↑x ∈ dom(g))))) and 
     (↑x ∈ dom(⊕(L))))

Lemma: fpf_join_cons_lemma
v,u,eq:Top.  (⊕([u v]) u ⊕ ⊕(v))

Lemma: fpf_join_nil_lemma
eq:Top. (⊕([]) ~ ⊗)

Lemma: fpf-sub-join-symmetry
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> B[a]].  f ⊕ g ⊆ g ⊕ supposing || g

Definition: fpf-union-join
fpf-union-join(eq;R;f;g) ==  <(fst(f)) filter(λa.(¬ba ∈ dom(f));fst(g)), λa.fpf-union(f;g;eq;R;a)>

Lemma: fpf-union-join_wf
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g:a:A fp-> B[a] List]. ∀[R:⋂a:A. ((B[a] List) ⟶ B[a] ⟶ 𝔹)].
  (fpf-union-join(eq;R;f;g) ∈ a:A fp-> B[a] List)

Lemma: fpf-union-join-dom
[A:Type]
  ∀eq:EqDecider(A). ∀f,g:a:A fp-> Top. ∀x:A. ∀R:Top.
    (↑x ∈ dom(fpf-union-join(eq;R;f;g)) ⇐⇒ (↑x ∈ dom(f)) ∨ (↑x ∈ dom(g)))

Lemma: fpf-domain-union-join
[A:Type]
  ∀f:a:A fp-> Top List. ∀g:a:A fp-> Top. ∀eq:EqDecider(A). ∀x:A. ∀R:Top.
    ((x ∈ fpf-domain(fpf-union-join(eq;R;f;g))) ⇐⇒ (x ∈ fpf-domain(f)) ∨ (x ∈ fpf-domain(g)))

Lemma: fpf-union-join-ap
[f,g,eq,x,R:Top].  (fpf-union-join(eq;R;f;g)(x) fpf-union(f;g;eq;R;x))

Lemma: fpf-union-join-member
[A:Type]
  ∀eq:EqDecider(A)
    ∀[B:A ⟶ Type]
      ∀f,g:a:A fp-> B[a] List. ∀R:⋂a:A. ((B[a] List) ⟶ B[a] ⟶ 𝔹). ∀a:A.
        ∀x:B[a]. ((x ∈ fpf-union-join(eq;R;f;g)(a))  (((↑a ∈ dom(f)) ∧ (x ∈ f(a))) ∨ ((↑a ∈ dom(g)) ∧ (x ∈ g(a))))) 
        supposing ↑a ∈ dom(fpf-union-join(eq;R;f;g))

Lemma: fpf-union-compatible-property
[T,V:Type].
  ∀eq:EqDecider(T)
    ∀[X:T ⟶ Type]
      ∀R:(V List) ⟶ V ⟶ 𝔹
        (∀A,B,C:t:T fp-> X[t] List.
           (fpf-union-compatible(T;V;t.X[t];eq;R;A;B)
            fpf-union-compatible(T;V;t.X[t];eq;R;C;A)
            fpf-union-compatible(T;V;t.X[t];eq;R;C;B)
            fpf-union-compatible(T;V;t.X[t];eq;R;C;fpf-union-join(eq;R;A;B)))) supposing 
           ((∀L1,L2:V List. ∀x:V.  (↑(R (L1 L2) x)) supposing ((↑(R L2 x)) and (↑(R L1 x)))) and 
           (∀L1,L2:V List. ∀x:V.  (L1 ⊆ L2  ↑(R L1 x) supposing ↑(R L2 x)))) 
      supposing ∀t:T. (X[t] ⊆V)

Lemma: fpf-contains-union-join-left2
[A:Type]. ∀[B:A ⟶ Type].
  ∀eq:EqDecider(A). ∀f,h,g:a:A fp-> B[a] List. ∀R:⋂a:A. ((B[a] List) ⟶ B[a] ⟶ 𝔹).
    (h ⊆⊆  h ⊆⊆ fpf-union-join(eq;R;f;g))

Lemma: fpf-contains-union-join-right2
[A,V:Type]. ∀[B:A ⟶ Type].
  ∀eq:EqDecider(A). ∀f,h,g:a:A fp-> B[a] List. ∀R:(V List) ⟶ V ⟶ 𝔹.
    fpf-union-compatible(A;V;x.B[x];eq;R;f;g)  h ⊆⊆  h ⊆⊆ fpf-union-join(eq;R;f;g) 
    supposing fpf-single-valued(A;eq;x.B[x];V;g) 
  supposing ∀a:A. (B[a] ⊆V)

Lemma: fpf-sub-val
[A:Type]. ∀[B:A ⟶ Type].
  ∀eq:EqDecider(A). ∀f,g:a:A fp-> B[a]. ∀x:A.
    ∀[P:a:A ⟶ B[a] ⟶ ℙ]. != f(x) ==> P[x;z]  != g(x) ==> P[x;z] supposing g ⊆ f

Lemma: fpf-sub-val2
[A,A':Type].
  ∀[B:A ⟶ Type]
    ∀eq:EqDecider(A'). ∀f,g:a:A fp-> B[a]. ∀x:A'.
      ∀[P,Q:a:A ⟶ B[a] ⟶ ℙ].
        ((∀x:A. ∀z:B[x].  (P[x;z]  Q[x;z]))  != f(x) ==> P[x;z]  != g(x) ==> Q[x;z] supposing g ⊆ f) 
  supposing strong-subtype(A;A')

Lemma: fpf-sub-val3
[A:Type]. ∀[B,C:A ⟶ Type].
  ∀eq:EqDecider(A). ∀f:a:A fp-> B[a]. ∀g:a:A fp-> C[a]. ∀x:A.
    ∀[P:a:A ⟶ B[a] ⟶ ℙ]. ∀[Q:a:A ⟶ C[a] ⟶ ℙ].
      ((∀x:A. ((C[x] ⊆B[x]) c∧ (P[x;g(x)]  Q[x;g(x)])) supposing ((↑x ∈ dom(f)) and (↑x ∈ dom(g))))
       {z != f(x) ==> P[y;z]  != g(x) ==> Q[y;z] supposing g ⊆ f})

Definition: fpf-const
|-fpf-> ==  <L, λx.v>

Lemma: fpf-const_wf
[A,B:Type]. ∀[L:A List]. ∀[v:B].  (L |-fpf-> v ∈ a:A fp-> B)

Lemma: fpf-const-dom
[A:Type]. ∀eq:EqDecider(A). ∀L:A List. ∀v:Top. ∀x:A.  (↑x ∈ dom(L |-fpf-> v) ⇐⇒ (x ∈ L))

Definition: fpf-single
==  <[x], λx.v>

Lemma: fpf-single_wf
[A:𝕌{j}]. ∀[B:A ⟶ Type]. ∀[x:A]. ∀[v:B[x]].  (x v ∈ x:A fp-> B[x])

Lemma: fpf-single_wf2
[A,B:Type]. ∀[x:A]. ∀[v:B]. ∀[eqa:EqDecider(A)].  (x v ∈ a:A fp-> B(a)?Top)

Lemma: fpf-single_wf3
[A,B:Type]. ∀[x:A].  (x B ∈ a:A fp-> Type)

Definition: mk_fpf
mk_fpf(L;f) ==  <L, f>

Lemma: mk_fpf_wf
[A:Type]. ∀[L:A List]. ∀[B:A ⟶ Type]. ∀[f:a:{a:A| (a ∈ L)}  ⟶ B[a]].  (mk_fpf(L;f) ∈ a:A fp-> B[a])

Lemma: mk_fpf_dom_lemma
f,L:Top.  (fpf-domain(mk_fpf(L;f)) L)

Lemma: mk_fpf_ap_lemma
x,eq,f,L:Top.  (mk_fpf(L;f)(x) x)

Lemma: fpf-single-sub-reflexive
[A:Type]. ∀[B:A ⟶ Type]. ∀[x:A]. ∀[v:B[x]]. ∀[eqa:EqDecider(A)].  v ⊆ v

Lemma: fpf-cap-single1
[A:Type]. ∀[eq:EqDecider(A)]. ∀[x:A]. ∀[v,z:Top].  (x v(x)?z v)

Lemma: fpf-split
[A:Type]
  ∀eq:EqDecider(A)
    ∀[B:A ⟶ Type]
      ∀f:a:A fp-> B[a]
        ∀[P:A ⟶ ℙ]
          ((∀a:A. Dec(P[a]))
           (∃fp,fnp:a:A fp-> B[a]
               ((f ⊆ fp ⊕ fnp ∧ fp ⊕ fnp ⊆ f)
               ∧ ((∀a:A. P[a] supposing ↑a ∈ dom(fp)) ∧ (∀a:A. ¬P[a] supposing ↑a ∈ dom(fnp)))
               ∧ fpf-domain(fp) ⊆ fpf-domain(f)
               ∧ fpf-domain(fnp) ⊆ fpf-domain(f))))

Lemma: fpf-cap-single-join
[A:Type]. ∀[eq:EqDecider(A)]. ∀[x:A]. ∀[v,z,f:Top].  (x v ⊕ f(x)?z v)

Lemma: fpf_ap_single_lemma
y,eq,v,x:Top.  (x v(y) v)

Lemma: fpf-ap-single
[eq,x,v,y:Top].  (x v(y) v)

Lemma: fpf-cap-single
[A:Type]. ∀[eq:EqDecider(A)]. ∀[x,y:A]. ∀[v,z:Top].  (x v(y)?z if eq then else fi )

Lemma: fpf-conversion-test
2 ⊕ 2 ⊕ = <[4; 6; 7], λx.if x ∈b [4; 6] then else fi > ∈ i:ℤ fp-> ℤ

Lemma: fpf-val-single1
[A:Type]. ∀[eq:EqDecider(A)]. ∀[x:A]. ∀[v,P:Top].  (z != v(x) ==> P[a;z] True  P[x;v])

Definition: fpf-add-single
fx ==  f ⊕ v

Lemma: fpf-add-single_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[x:A]. ∀[v:B[x]]. ∀[eq:EqDecider(A)]. ∀[f:x:A fp-> B[x]].  (fx v ∈ x:A fp-> B[x])

Definition: fpf-vals
fpf-vals(eq;P;f) ==  let filter(P;remove-repeats(eq;fst(f))) in zip(L;map(snd(f);L))

Lemma: fpf-vals_wf
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[P:A ⟶ 𝔹]. ∀[f:x:A fp-> B[x]].  (fpf-vals(eq;P;f) ∈ (x:{a:A| ↑(P a)}  ×\000C B[x]) List)

Lemma: member-fpf-vals
[A:Type]
  ∀eq:EqDecider(A)
    ∀[B:A ⟶ Type]
      ∀P:A ⟶ 𝔹. ∀f:x:A fp-> B[x]. ∀x:A. ∀v:B[x].
        ((<x, v> ∈ fpf-vals(eq;P;f)) ⇐⇒ {((↑x ∈ dom(f)) ∧ (↑(P x))) ∧ (v f(x) ∈ B[x])})

Lemma: member-fpf-vals2
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[P:A ⟶ 𝔹]. ∀[f:x:A fp-> B[x]]. ∀[x:{a:A| ↑(P a)} ]. ∀[v:B[x]].
  {(↑x ∈ dom(f)) ∧ (v f(x) ∈ B[x])} supposing (<x, v> ∈ fpf-vals(eq;P;f))

Lemma: filter-fpf-vals
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[P,Q:A ⟶ 𝔹]. ∀[f:x:A fp-> B[x]].
  (filter(λpL.Q[fst(pL)];fpf-vals(eq;P;f)) fpf-vals(eq;λa.((P a) ∧b (Q a));f))

Lemma: fpf-vals-singleton
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[P:A ⟶ 𝔹]. ∀[f:x:A fp-> B[x]]. ∀[a:A].
  (fpf-vals(eq;P;f) [<a, f(a)>] ∈ ((x:A × B[x]) List)) supposing ((∀b:A. (↑(P b) ⇐⇒ a ∈ A)) and (↑a ∈ dom(f)))

Lemma: fpf-vals-nil
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[P:A ⟶ 𝔹]. ∀[f:x:A fp-> B[x]]. ∀[a:A].
  (fpf-vals(eq;P;f) []) supposing ((∀b:A. (↑(P b) ⇐⇒ a ∈ A)) and (¬↑a ∈ dom(f)))

Definition: fpf-all
x∈dom(f). v=f(x)   P[x; v] ==  ∀x:A. ((↑x ∈ dom(f))  P[x; f(x)])

Lemma: fpf-all_wf
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f:x:A fp-> B[x]]. ∀[P:x:{x:A| ↑x ∈ dom(f)}  ⟶ B[x] ⟶ ℙ].
  (∀x∈dom(f). v=f(x)   P[x;v] ∈ ℙ)

Definition: fpf-map
fpf-map(a,v.f[a; v];x) ==  map(λa.f[a; (snd(x)) a];fst(x))

Lemma: fpf-map_wf
[A,C:Type]. ∀[B:A ⟶ Type]. ∀[x:a:A fp-> B[a]]. ∀[f:a:{a:A| (a ∈ fpf-domain(x))}  ⟶ B[a] ⟶ C].
  (fpf-map(a,v.f[a;v];x) ∈ List)

Definition: fpf-accum
fpf-accum(z,a,v.f[z; a; v];y;x) ==
  accumulate (with value and list item a):
   f[z; a; (snd(x)) a]
  over list:
    fst(x)
  with starting value:
   y)

Lemma: fpf-accum_wf
[A,C:Type]. ∀[B:A ⟶ Type]. ∀[x:a:A fp-> B[a]]. ∀[y:C]. ∀[f:C ⟶ a:A ⟶ B[a] ⟶ C].
  (fpf-accum(z,a,v.f[z;a;v];y;x) ∈ C)

Definition: fpf-rename
rename(r;f) ==  <map(r;fst(f)), λx.((snd(f)) hd(filter(λy.(eq (r y) x);fst(f))))>

Lemma: fpf-rename_wf
[A,C:Type]. ∀[B:A ⟶ Type]. ∀[D:C ⟶ Type]. ∀[eq:EqDecider(C)]. ∀[r:A ⟶ C]. ∀[f:a:A fp-> B[a]].
  rename(r;f) ∈ c:C fp-> D[c] supposing ∀a:A. (D[r a] B[a] ∈ Type)

Lemma: fpf-rename-dom
[A,C:Type]. ∀[B:A ⟶ Type].
  ∀eqa:EqDecider(A). ∀eqc:EqDecider(C). ∀r:A ⟶ C. ∀f:a:A fp-> B[a]. ∀c:C.
    (↑c ∈ dom(rename(r;f)) ⇐⇒ ∃a:A. ((↑a ∈ dom(f)) c∧ (c (r a) ∈ C)))

Lemma: fpf-rename-dom2
[A,C:Type]. ∀[eqa:EqDecider(A)]. ∀[eqc:EqDecider(C)]. ∀[eqc':Top]. ∀[r:A ⟶ C]. ∀[f:a:A fp-> Top]. ∀[a:A].
  {↑a ∈ dom(rename(r;f)) supposing ↑a ∈ dom(f)}

Lemma: fpf-rename-ap
[A,C:Type]. ∀[B:A ⟶ Type]. ∀[eqa:EqDecider(A)]. ∀[eqc:EqDecider(C)]. ∀[r:A ⟶ C]. ∀[f:a:A fp-> B[a]]. ∀[a:A].
  (rename(r;f)(r a) f(a) ∈ B[a]) supposing ((↑a ∈ dom(f)) and Inj(A;C;r))

Lemma: fpf-rename-ap2
[A,C:Type]. ∀[B:A ⟶ Type]. ∀[eqa:EqDecider(A)]. ∀[eqc,eqc':EqDecider(C)]. ∀[r:A ⟶ C]. ∀[f:a:A fp-> B[a]]. ∀[a:A].
  (rename(r;f)(r a) f(a) ∈ B[a]) supposing ((↑a ∈ dom(f)) and Inj(A;C;r))

Lemma: fpf-rename-cap
[A,C,B:Type]. ∀[eqa:EqDecider(A)]. ∀[eqc:EqDecider(C)]. ∀[r:A ⟶ C]. ∀[f:a:A fp-> B]. ∀[a:A]. ∀[z:B].
  rename(r;f)(r a)?z f(a)?z ∈ supposing Inj(A;C;r)

Lemma: fpf-rename-cap2
[A,C,B:Type]. ∀[eqa:EqDecider(A)]. ∀[eqc,eqc':EqDecider(C)]. ∀[r:A ⟶ C]. ∀[f:a:A fp-> B]. ∀[a:A]. ∀[z:B].
  rename(r;f)(r a)?z f(a)?z ∈ supposing Inj(A;C;r)

Lemma: fpf-rename-cap3
[A,C,B:Type]. ∀[eqa:EqDecider(A)]. ∀[eqc,eqc':EqDecider(C)]. ∀[r:A ⟶ C]. ∀[f:a:A fp-> B]. ∀[a:A]. ∀[z:B]. ∀[c:C].
  (rename(r;f)(c)?z f(a)?z ∈ B) supposing ((c (r a) ∈ C) and Inj(A;C;r))

Definition: fpf-inv-rename
fpf-inv-rename(r;rinv;f) ==  <mapfilter(λx.outl(rinv x);λx.isl(rinv x);fst(f)), (snd(f)) r>

Lemma: fpf-inv-rename_wf
[A,C:Type]. ∀[B:A ⟶ Type]. ∀[D:C ⟶ Type]. ∀[rinv:C ⟶ (A?)]. ∀[r:A ⟶ C]. ∀[f:c:C fp-> D[c]].
  (fpf-inv-rename(r;rinv;f) ∈ a:A fp-> B[a]) supposing ((∀a:A. (D[r a] B[a] ∈ Type)) and inv-rel(A;C;r;rinv))

Definition: fpf-compose
==  <fst(f), (snd(f))>

Lemma: fpf-compose_wf
[A:Type]. ∀[B,C:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[g:⋂a:A. (B[a] ⟶ C[a])].  (g f ∈ a:A fp-> C[a])

Lemma: fpf_dom_compose_lemma
f,g,x,eq:Top.  (x ∈ dom(g f) x ∈ dom(f))

Lemma: fpf_ap_compose_lemma
x,eq,f,g:Top.  (g f(x) f(x))

Lemma: fpf-dom-compose
[x:Top]. ∀[f:a:Top fp-> Top]. ∀[g,eq:Top].  (x ∈ dom(g f) x ∈ dom(f))

Lemma: fpf-ap-compose
[x:Top]. ∀[f:a:Top fp-> Top]. ∀[g,eq:Top].  (g f(x) f(x))

Definition: compose-fpf
compose-fpf(a;b;f) ==  <mapfilter(λx.outl(a x);λx.isl(a x);fpf-domain(f)), (snd(f)) b>

Lemma: compose-fpf_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:x:A fp-> B[x]]. ∀[C:Type]. ∀[a:A ⟶ (C?)]. ∀[b:C ⟶ A].
  compose-fpf(a;b;f) ∈ y:C fp-> B[b y] supposing ∀y:A. ((↑isl(a y))  ((b outl(a y)) y ∈ A))

Lemma: compose-fpf-dom
[A:Type]. ∀[B:A ⟶ Type].
  ∀f:x:A fp-> B[x]
    ∀[C:Type]
      ∀a:A ⟶ (C?). ∀b:C ⟶ A. ∀y:C.
        ((y ∈ fpf-domain(compose-fpf(a;b;f))) ⇐⇒ ∃x:A. ((x ∈ fpf-domain(f)) ∧ ((↑isl(a x)) c∧ (y outl(a x) ∈ C))))

Lemma: fpf-sub-reflexive
[A:Type]. ∀[B:A ⟶ Type]. ∀[eq:EqDecider(A)]. ∀[f:a:A fp-> B[a]].  f ⊆ f

Definition: mkfpf
mkfpf(a;b) ==  <a, b>

Lemma: mkfpf_wf
[A:Type]. ∀[a:A List]. ∀[b:a:{a@0:A| (a@0 ∈ a)}  ⟶ Top].  (mkfpf(a;b) ∈ a:A fp-> Top)

Lemma: fpf-join-compatible-left
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B,C,D,E,F,G:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[g:a:A fp-> C[a]]. ∀[h:a:A fp-> D[a]].
  ({(f ⊕ || h) supposing (g || and || h)}) supposing 
     ((∀a:A. (E[a] ⊆G[a])) and 
     (∀a:A. (F[a] ⊆G[a])) and 
     (∀a:A. (D[a] ⊆F[a])) and 
     (∀a:A. (D[a] ⊆E[a])) and 
     (∀a:A. (C[a] ⊆F[a])) and 
     (∀a:A. (B[a] ⊆E[a])))

Lemma: fpf-join-compatible-right
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B,C,D,E,F,G:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[g:a:A fp-> C[a]]. ∀[h:a:A fp-> D[a]].
  ({(h || f ⊕ g) supposing (h || and || f)}) supposing 
     ((∀a:A. (E[a] ⊆G[a])) and 
     (∀a:A. (F[a] ⊆G[a])) and 
     (∀a:A. (D[a] ⊆F[a])) and 
     (∀a:A. (D[a] ⊆E[a])) and 
     (∀a:A. (C[a] ⊆F[a])) and 
     (∀a:A. (B[a] ⊆E[a])))

Lemma: fpf-compatible-self
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]].  || f

Lemma: fpf-compatible-join
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g,h:a:A fp-> B[a]].  (h || f ⊕ g) supposing (h || and || f)

Lemma: fpf-compatible-join-iff
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g,h:a:A fp-> B[a]].
  uiff(h || f ⊕ g;h || f ∧ || g) supposing || g

Lemma: fpf-compatible-symmetry
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g:a:A fp-> B[a]].  || supposing || g

Lemma: fpf-disjoint-compatible
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g:a:A fp-> B[a]].  || supposing l_disjoint(A;fst(f);fst(g))

Lemma: fpf-compatible-update
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g:a:A fp-> B[a]].  f ⊕ || f

Lemma: fpf-compatible-update2
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g:a:A fp-> B[a]].  || f ⊕ g

Lemma: fpf-compatible-update3
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g,h:a:A fp-> B[a]].  h ⊕ || h ⊕ supposing || g

Lemma: fpf-compatible-join2
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g,h:a:A fp-> B[a]].  (f ⊕ || h) supposing (g || and || h)

Lemma: fpf-compatible-singles
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[x,y:A]. ∀[v:B[x]]. ∀[u:B[y]].
  || supposing (x y ∈ A)  (v u ∈ B[x])

Lemma: fpf-compatible-singles-trivial
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:Top]. ∀[x,y:A]. ∀[v,u:Top].  || supposing ¬(x y ∈ A)

Lemma: fpf-single-dom
[A:Type]. ∀[eq:EqDecider(A)]. ∀[x,y:A]. ∀[v:Top].  uiff(↑x ∈ dom(y v);x y ∈ A)

Lemma: fpf-single-dom-sq
[A:Type]. ∀[eq:EqDecider(A)]. ∀[x,y:A]. ∀[v:Top].  (x ∈ dom(y v) eq x)

Lemma: fpf-join-single-property
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[a:A]. ∀[v:B[a]]. ∀[eq:EqDecider(A)]. ∀[b:A].
  ({(↑b ∈ dom(f)) ∧ (f ⊕ v(b) f(b) ∈ B[b])}) supposing ((↑b ∈ dom(f ⊕ v)) and (b a ∈ A)))

Lemma: fpf-compatible-single
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[x:A]. ∀[v:B[x]].  || supposing ¬↑x ∈ dom(f)

Lemma: fpf-compatible-single-iff
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[x:A]. ∀[v:B[x]].
  uiff(f || v;v f(x) ∈ B[x] supposing ↑x ∈ dom(f))

Lemma: fpf-compatible-single2
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[x:A]. ∀[v:B[x]].  || supposing ¬↑x ∈ dom(f)

Lemma: fpf-compatible-singles-iff
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[x,y:A]. ∀[v:B[x]]. ∀[u:B[y]].
  uiff(x || u;v u ∈ B[x] supposing y ∈ A)

Lemma: fpf-decompose
[A:Type]
  ∀eq:EqDecider(A)
    ∀[B:A ⟶ Type]
      ∀f:a:A fp-> B[a]
        ∃g:a:A fp-> B[a]
         ∃a:A
          ∃b:B[a]
           ((f ⊆ g ⊕ b ∧ g ⊕ b ⊆ f)
           ∧ (∀a':A. ¬(a' a ∈ A) supposing ↑a' ∈ dom(g))
           ∧ ||fpf-domain(g)|| < ||fpf-domain(f)||) 
        supposing 0 < ||fpf-domain(f)||

Lemma: fpf-compatible-join-cap
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g:a:A fp-> B[a]]. ∀[x:A]. ∀[z:B[x]].
  f ⊕ g(x)?z g(x)?f(x)?z ∈ B[x] supposing || g

Lemma: fpf-ap-equal
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f:a:A fp-> B[a]]. ∀[x:A]. ∀[v:B[x]].
  (f(x) v ∈ B[x]) supposing ((↑x ∈ dom(f)) and || v)

Lemma: fpf-join-dom-decl
f,g:x:Id fp-> Type. ∀x:Id.  (↑x ∈ dom(f ⊕ g) ⇐⇒ (↑x ∈ dom(f)) ∨ (↑x ∈ dom(g)))

Lemma: fpf-join-dom-da
f,g:x:Knd fp-> Type. ∀x:Knd.  (↑x ∈ dom(f ⊕ g) ⇐⇒ (↑x ∈ dom(f)) ∨ (↑x ∈ dom(g)))

Lemma: fpf-cap-join-subtype
[A:Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> Type]. ∀[a:A].  (f ⊕ g(a)?Top ⊆f(a)?Top)

Lemma: fpf-cap-join-subtype2
[A:Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> Type]. ∀[a:A].  f ⊕ g(a)?Top ⊆g(a)?Top supposing || g

Lemma: fpf-all-empty
[A:Type]. ∀eq,P:Top.  (∀y∈dom(⊗). w=⊗(y)   P[y;w] ⇐⇒ True)

Lemma: fpf-all-single
[A:Type]
  ∀eq:EqDecider(A)
    ∀[B:A ⟶ Type]. ∀[P:x:A ⟶ B[x] ⟶ ℙ].  ∀x:A. ∀v:B[x].  (∀y∈dom(x v). w=x v(y)   P[y;w] ⇐⇒ P[x;v])

Lemma: fpf-all-single-decl
[A:Type]. ∀eq:EqDecider(A). ∀[P:x:A ⟶ Type ⟶ ℙ]. ∀x:A. ∀[v:Type]. (∀y∈dom(x v). w=x v(y)   P[y;w] ⇐⇒ P[x;v])

Lemma: fpf-all-join-decl
[A:Type]
  ∀eq:EqDecider(A)
    ∀[P:x:A ⟶ Type ⟶ ℙ]
      ∀f,g:x:A fp-> Type.
        (∀y∈dom(f). w=f(y)   P[y;w]  ∀y∈dom(g). w=g(y)   P[y;w]  ∀y∈dom(f ⊕ g). w=f ⊕ g(y)   P[y;w])

Definition: non-void-decl
non-void(d) ==  ∀x∈dom(d). A=d(x)   A

Lemma: non-void-decl_wf
[T:Type]. ∀[eq:EqDecider(T)]. ∀[d:a:T fp-> Type].  (non-void(d) ∈ ℙ')

Lemma: non-void-decl-join
[T:Type]. ∀eq:EqDecider(T). ∀d1,d2:a:T fp-> Type.  (non-void(d1)  non-void(d2)  non-void(d1 ⊕ d2))

Lemma: non-void-decl-single
[T,A:Type].  ∀x:T. ∀eq:EqDecider(T).  (A  non-void(x A))

Definition: atom-free-decl
AtomFree(d) ==  ∀x∈dom(d). A=d(x)   atom-free{1:n}(Type; A)

Lemma: fpf-empty-compatible-right
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:Top]. ∀[f:a:A fp-> Top].  || ⊗

Lemma: fpf-empty-compatible-left
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:Top]. ∀[f:a:A fp-> Top].  ⊗ || f

Lemma: fpf-compatible-triple
[T:Type]. ∀[eq:EqDecider(T)]. ∀[f,g,h:x:T fp-> Type].
  ({(g ⊆ h ⊕ f ⊕ g ∧ f ⊆ h ⊕ f ⊕ g) ∧ h ⊕ g ⊆ h ⊕ f ⊕ g ∧ h ⊕ f ⊆ h ⊕ f ⊕ g}) supposing (h || and || and || g)

Definition: fpf-dom-list
fpf-dom-list(f) ==  fst(f)

Lemma: fpf-dom-list_wf
[A:Type]. ∀[eq:EqDecider(A)]. ∀[f:a:A fp-> Top].  (fpf-dom-list(f) ∈ {a:A| ↑a ∈ dom(f)}  List)

Lemma: member-fpf-dom
[A:Type]. ∀eq:EqDecider(A). ∀f:a:A fp-> Top. ∀x:A.  (↑x ∈ dom(f) ⇐⇒ (x ∈ fst(f)))

Definition: fpf-restrict
fpf-restrict(f;P) ==  mk_fpf(filter(P;fpf-domain(f));snd(f))

Lemma: fpf-restrict_wf
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:x:A fp-> B[x]]. ∀[P:A ⟶ 𝔹].  (fpf-restrict(f;P) ∈ x:{x:A| ↑(P x)}  fp-> B[x])

Lemma: fpf-restrict_wf2
[A:Type]. ∀[B:A ⟶ Type]. ∀[f:x:A fp-> B[x]]. ∀[P:A ⟶ 𝔹].  (fpf-restrict(f;P) ∈ x:A fp-> B[x])

Lemma: domain_fpf_restrict_lemma
P,f:Top.  (fpf-domain(fpf-restrict(f;P)) filter(P;fpf-domain(f)))

Lemma: ap_fpf_restrict_lemma
x,eq,P,f:Top.  (fpf-restrict(f;P)(x) f(x))

Lemma: fpf-restrict-domain
[f,P:Top].  (fpf-domain(fpf-restrict(f;P)) filter(P;fpf-domain(f)))

Lemma: fpf-restrict-dom
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f:x:A fp-> B[x]]. ∀[P:A ⟶ 𝔹]. ∀[x:A].
  uiff(↑x ∈ dom(fpf-restrict(f;P));{(↑x ∈ dom(f)) ∧ (↑(P x))})

Lemma: fpf-restrict-ap
[f,P,eq,x:Top].  (fpf-restrict(f;P)(x) f(x))

Lemma: fpf-restrict-cap
[A:Type]. ∀[P:A ⟶ 𝔹]. ∀[x:A].
  ∀[f:x:A fp-> Top]. ∀[eq:EqDecider(A)]. ∀[z:Top].  (fpf-restrict(f;P)(x)?z f(x)?z) supposing ↑(P x)

Lemma: fpf-restrict-compatible
[A:Type]. ∀[P:A ⟶ 𝔹]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g:x:A fp-> B[x]].
  fpf-restrict(f;P) || supposing || g

Lemma: fpf-restrict-compatible2
[A:Type]. ∀[P:A ⟶ 𝔹]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[f,g:x:A fp-> B[x]].
  || fpf-restrict(g;P) supposing || g

Definition: lnk-decl
lnk-decl(l;dt) ==  <map(λtg.rcv(l,tg);fst(dt)), λk.dt(snd(outl(k)))>

Lemma: lnk-decl_wf
[l:IdLnk]. ∀[dt:tg:Id fp-> Type].  (lnk-decl(l;dt) ∈ k:Knd fp-> Type)

Lemma: lnk-decl_wf-hasloc
[l:IdLnk]. ∀[dt:tg:Id fp-> Type].  (lnk-decl(l;dt) ∈ k:{k:Knd| ↑hasloc(k;destination(l))}  fp-> Type)

Lemma: lnk-decl-cap
[l:IdLnk]. ∀[dt:tg:Id fp-> Type]. ∀[tg:Id]. ∀[T:Type].  (lnk-decl(l;dt)(rcv(l,tg))?T dt(tg)?T)

Lemma: lnk-decl-dom
[l:IdLnk]. ∀[dt:tg:Id fp-> Type]. ∀[tg:Id].  (rcv(l,tg) ∈ dom(lnk-decl(l;dt)) tg ∈ dom(dt))

Lemma: lnk-decl-dom-single
[l:IdLnk]. ∀[k:Knd]. ∀[tg:Id]. ∀[v:Top].  (k ∈ dom(lnk-decl(l;tg v)) rcv(l,tg) k)

Lemma: lnk-decl-dom-join
[l:IdLnk]. ∀[k:Knd]. ∀[dt1,dt2:tg:Id fp-> Type].
  (k ∈ dom(lnk-decl(l;dt1 ⊕ dt2)) k ∈ dom(lnk-decl(l;dt1)) ∨bk ∈ dom(lnk-decl(l;dt2)))

Lemma: lnk-decl-dom-not
[l:IdLnk]. ∀[dt:tg:Id fp-> Type]. ∀[a:Id].  (locl(a) ∈ dom(lnk-decl(l;dt)) ff)

Lemma: lnk-decl-dom2
[l,l2:IdLnk]. ∀[dt:tg:Id fp-> Type]. ∀[tg:Id].  l2 l ∈ IdLnk supposing ↑rcv(l2,tg) ∈ dom(lnk-decl(l;dt))

Lemma: lnk-decl-cap2
[l1,l2:IdLnk]. ∀[dt:tg:Id fp-> Type]. ∀[tg:Id]. ∀[T:Type].
  (lnk-decl(l1;dt)(rcv(l2,tg))?T if l1 l2 then dt(tg)?T else fi )

Lemma: lnk-decl-ap
[k:Knd]. ∀[l:IdLnk]. ∀[dt:x:Id fp-> Type].  lnk-decl(l;dt)(k) dt(tag(k)) supposing ↑k ∈ dom(lnk-decl(l;dt))

Lemma: lnk-decl-dom-implies
[k:Knd]. ∀[l:IdLnk]. ∀[dt:x:Id fp-> Type].  {(↑isrcv(k)) c∧ (↑tag(k) ∈ dom(dt))} supposing ↑k ∈ dom(lnk-decl(l;dt))

Lemma: lnk-decl-compatible-single
[l:IdLnk]. ∀[dt:tg:Id fp-> Type]. ∀[knd:Knd]. ∀[T:Type].
  lnk-decl(l;dt) || knd 
  supposing (↑isrcv(knd))  (↑lnk(knd) l)  (↑tag(knd) ∈ dom(dt))  (T dt(tag(knd)) ∈ Type)

Lemma: lnk-decl-compatible-single2
[l:IdLnk]. ∀[dt:tg:Id fp-> Type]. ∀[knd:Knd]. ∀[T:Type].
  lnk-decl(l;dt) || knd supposing (↑isrcv(knd))  (lnk(knd) l ∈ IdLnk)  (T dt(tag(knd))?Void ∈ Type)

Lemma: lnk-decls-compatible
[l1,l2:IdLnk]. ∀[d1,d2:tg:Id fp-> Type].  lnk-decl(l1;d1) || lnk-decl(l2;d2) supposing (l1 l2 ∈ IdLnk)  d1 || d2

Lemma: l_disjoint-fpf-dom
[A:Type]. ∀[eq:EqDecider(A)]. ∀[f:a:A fp-> Top]. ∀[L:A List].
  uiff(l_disjoint(A;fst(f);L);∀[a:A]. ¬(a ∈ L) supposing ↑a ∈ dom(f))

Lemma: l_disjoint-fpf-join-dom
[A:Type]. ∀[eq:EqDecider(A)]. ∀[f,g:a:A fp-> Top]. ∀[L:A List].
  uiff(l_disjoint(A;fst(f ⊕ g);L);l_disjoint(A;fst(f);L) ∧ l_disjoint(A;fst(g);L))

Definition: pairs-fpf
fpf(L) ==
  <remove-repeats(eq1;map(λp.(fst(p));L)), λx.reduce(λp,l. if eqof(eq1) (fst(p)) then insert(snd(p);l) else fi ;[];L\000C)>

Lemma: pairs-fpf_wf
[A,B:Type]. ∀[eq1:EqDecider(A)]. ∀[eq2:EqDecider(B)]. ∀[L:(A × B) List].  (fpf(L) ∈ a:A fp-> List)

Lemma: pairs-fpf_property
[A,B:Type].
  ∀eq1:EqDecider(A). ∀eq2:EqDecider(B). ∀L:(A × B) List.
    (no_repeats(A;fpf-domain(fpf(L)))
    ∧ (∀a:A. ((a ∈ fpf-domain(fpf(L))) ⇐⇒ ∃b:B. (<a, b> ∈ L)))
    ∧ ∀a∈dom(fpf(L)). l=fpf(L)(a)   no_repeats(B;l) ∧ (∀b:B. ((b ∈ l) ⇐⇒ (<a, b> ∈ L))))

Lemma: no_repeats-pairs-fpf
[A,B:Type]. ∀[eq1:EqDecider(A)]. ∀[eq2:EqDecider(B)]. ∀[L:(A × B) List].  no_repeats(A;fpf-domain(fpf(L)))

Definition: fpf-normalize
fpf-normalize(eq;g) ==  reduce(λx,f. (snd(g)) x ⊕ f;⊗;fst(g))

Lemma: fpf-normalize_wf
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[g:x:A fp-> B[x]].  (fpf-normalize(eq;g) ∈ x:A fp-> B[x])

Lemma: fpf-normalize-dom
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[g:x:A fp-> B[x]]. ∀[x:A].  (x ∈ dom(fpf-normalize(eq;g)) x ∈ dom(g))

Lemma: fpf-normalize-ap
[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ Type]. ∀[g:x:A fp-> B[x]]. ∀[x:A].
  fpf-normalize(eq;g)(x) g(x) ∈ B[x] supposing ↑x ∈ dom(g)

Definition: ma-valtype
Valtype(da;k) ==  da(k)?Top

Lemma: ma-valtype_wf
[da:z:Knd fp-> Type]. ∀[k:Knd].  (Valtype(da;k) ∈ Type)

Definition: ma-msgtype
Msgtype(da;k) ==  da(k)?Void

Lemma: ma-msgtype_wf
[da:k:Knd fp-> Type]. ∀[k:Knd].  (Msgtype(da;k) ∈ Type)

Definition: ma-state
State(ds) ==  x:Id ⟶ ds(x)?Top

Lemma: ma-state_wf
[ds:z:Id fp-> Type]. (State(ds) ∈ Type)

Definition: ma-tstate
timedState(ds) ==  x:Id ⟶ ℚ ⟶ ds(x)?Top

Lemma: ma-tstate_wf
[ds:z:Id fp-> Type]. (timedState(ds) ∈ Type)

Lemma: ma-valtype-subtype
[k:Knd]. ∀[da,da':a:Knd fp-> Type].  Valtype(da';k) ⊆Valtype(da;k) supposing da ⊆ da'

Lemma: ma-state-subtype
[ds,ds':ltg:Id fp-> Type].  State(ds') ⊆State(ds) supposing ds ⊆ ds'

Lemma: ma-state-subtype2
[ds,ds':ltg:Id fp-> Type].  State(ds') ⊆ State(ds) supposing ds ⊆ ds'

Definition: es-tags-dt
dt(l;tgs;da) ==  mk_fpf(tgs;λtg.da(rcv(l,tg))?Void)

Lemma: es-tags-dt_wf
[l:IdLnk]. ∀[tgs:Id List]. ∀[da:k:Knd fp-> Type].  (dt(l;tgs;da) ∈ tg:Id fp-> Type)

Lemma: es-tags-dt-cap
[l:IdLnk]. ∀[tgs:Id List]. ∀[da:k:Knd fp-> Type]. ∀[T:Top]. ∀[tg:Id].
  dt(l;tgs;da)(tg)?T da(rcv(l,tg))?Void supposing (tg ∈ tgs)

Definition: es-dt
dt(l;da) ==
  compose-fpf(λk.if isrcv(k) then if lnk(k) then inl tag(k) else inr ⋅  fi  else inr ⋅  fi tg.rcv(l,tg);da)

Lemma: es-dt_wf
[l:IdLnk]. ∀[da:k:Knd fp-> Type].  (dt(l;da) ∈ tg:Id fp-> Type)

Lemma: es-dt-dom
[l:IdLnk]. ∀[da:k:Knd fp-> Type]. ∀[tg:Id].  uiff(↑tg ∈ dom(dt(l;da));↑rcv(l,tg) ∈ dom(da))

Lemma: es-dt-ap
[da,l,tg:Top].  (dt(l;da)(tg) da(rcv(l,tg)))

Lemma: es-dt-cap
[da:k:Knd fp-> Type]. ∀[l:IdLnk]. ∀[tg:Id]. ∀[T:Top].  (dt(l;da)(tg)?T da(rcv(l,tg))?T)

Definition: normal-type
Normal(T) ==  T

Lemma: normal-type_wf
[T:Type]. (Normal(T) ∈ ℙ)

Lemma: normal-top
Normal(Top)

Definition: normal-ds
Normal(ds) ==  ∀x∈dom(ds). A=ds(x)   A

Lemma: normal-ds_wf
[ds:x:Id fp-> Type]. (Normal(ds) ∈ ℙ)

Lemma: implies-normal-ds
ds:x:Id fp-> Type. (∀x∈dom(ds). A=ds(x)    Normal(ds))

Lemma: normal-ds-single
x:Id. ∀[T:Type]. (Normal(T)  Normal(x T))

Lemma: normal-ds-join
ds1,ds2:x:Id fp-> Type.  (Normal(ds1)  Normal(ds2)  Normal(ds1 ⊕ ds2))

Definition: normal-da
Normal(da) ==  True

Lemma: normal-da_wf
[da:k:Knd fp-> Type]. (Normal(da) ∈ ℙ)

Lemma: normal-da-single
[x:Knd]. ∀[T:Type].  Normal(x T) supposing Dec(T)

Lemma: normal-da-join
[da1,da2:x:Knd fp-> Type].  (Normal(da1 ⊕ da2)) supposing (Normal(da2) and Normal(da1))

Lemma: normal-p-outcome
p:FinProbSpace. Normal(Outcome)

Definition: ds-agrees
ds-agrees(ds;x.T[x]) ==  ∀x:Id. ((↑x ∈ dom(ds))  T[x] ≡ ds(x))

Lemma: ds-agrees_wf
[ds:x:Id fp-> Type]. ∀[T:Id ⟶ Type].  (ds-agrees(ds;x.T[x]) ∈ ℙ)

Definition: ds-agrees-on
ds-agrees-on(ds;x;T) ==  (↑x ∈ dom(ds))  T ≡ ds(x)

Lemma: ds-agrees-on_wf
[ds:x:Id fp-> Type]. ∀[x:Id]. ∀[T:Type].  (ds-agrees-on(ds;x;T) ∈ ℙ)

Definition: da-agrees
da-agrees(da;k.T[k]) ==  ∀k:Knd. ((↑k ∈ dom(da))  T[k] ≡ da(k))

Lemma: da-agrees_wf
[da:k:Knd fp-> Type]. ∀[T:Knd ⟶ Type].  (da-agrees(da;k.T[k]) ∈ ℙ)

Definition: da-agrees-on
da-agrees-on(da;k;T) ==  (↑k ∈ dom(da))  T ≡ da(k)

Lemma: da-agrees-on_wf
[k:Knd]. ∀[T:Type]. ∀[da:k:Knd fp-> Type].  (da-agrees-on(da;k;T) ∈ ℙ)

Lemma: free-from-atom-fpf-ap
[a:Atom1]. ∀[A:Type]. ∀[eq:EqDecider(A)]. ∀[B:A ⟶ 𝕌']. ∀[f:x:A fp-> B[x]].
  ∀[x:A]. (a#f(x):B[x]) supposing ((↑x ∈ dom(f)) and a#x:A) supposing a#f:x:A fp-> B[x]

Definition: process
process(P.M[P];P.E[P]) ==  corec(P.M[P] ⟶ (P × E[P]))

Lemma: process_wf
[M,E:Type ⟶ Type].  (process(P.M[P];P.E[P]) ∈ Type)

Lemma: process-subtype
[M,E:Type ⟶ Type].
  (process(P.M[P];P.E[P]) ⊆(M[process(P.M[P];P.E[P])]
     ⟶ (process(P.M[P];P.E[P]) × E[process(P.M[P];P.E[P])]))) supposing 
     (Continuous+(P.E[P]) and 
     Continuous+(P.M[P]))

Lemma: process-valueall-type
[M,E:Type ⟶ Type].  valueall-type(process(P.M[P];P.E[P])) supposing M[Top]

Lemma: process-has-value
[M,E:Type ⟶ Type].  ∀[P:process(P.M[P];P.E[P])]. (P)↓ supposing M[Top]

Lemma: process-value-type
[M,E:Type ⟶ Type].  value-type(process(P.M[P];P.E[P])) supposing M[Top]

Definition: rec-process
RecProcess(s0;s,m.next[s; m]) ==  fix((λrec-dataflow,s0,m. let s',ext next[s0; m] in <rec-dataflow s', ext>)) s0

Lemma: rec-process_wf
[S,M,E:Type ⟶ Type].
  (∀[s0:S[process(P.M[P];P.E[P])]]. ∀[next:⋂T:{T:Type| process(P.M[P];P.E[P]) ⊆T} 
                                             (S[M[T] ⟶ (T × E[T])] ⟶ M[T] ⟶ (S[T] × E[T]))].
     (RecProcess(s0;s,m.next[s;m]) ∈ process(P.M[P];P.E[P]))) supposing 
     (Continuous+(T.E[T]) and 
     Continuous+(T.M[T]) and 
     Continuous+(T.S[T]))

Definition: recprocess
recprocess(s0;s,m.next[s; m];e,m,p.ext[e; m; p]) ==
  fix((λrecprocess,s0,m. let s',e next[s0; m] in <recprocess s', ext[e; m; recprocess s']>)) s0

Lemma: recprocess_wf
[S,M,E:Type ⟶ Type].
  (∀[s0:S[process(P.M[P];P.E[P])]]. ∀[next:⋂T:{T:Type| process(P.M[P];P.E[P]) ⊆T} 
                                             (S[M[T] ⟶ (T × E[T])] ⟶ M[T] ⟶ (S[T] × E[T]))]. ∀[ext:⋂T:Type
                                                                                                        (E[T]
                                                                                                        ⟶ M[T]
                                                                                                        ⟶ T
                                                                                                        ⟶ E[T])].
     (recprocess(s0;s,m.next[s;m];e,m,p.ext[e;m;p]) ∈ process(P.M[P];P.E[P]))) supposing 
     (Continuous+(T.E[T]) and 
     Continuous+(T.M[T]) and 
     Continuous+(T.S[T]))

Definition: null-process
null-process(n) ==  RecProcess(⋅;s,m.<s, n>)

Lemma: null-process_wf
[M,E:Type ⟶ Type].
  (∀[n:⋂T:Type. E[T]]. (null-process(n) ∈ process(P.M[P];P.E[P]))) supposing 
     (Continuous+(T.E[T]) and 
     Continuous+(T.M[T]))

Definition: iterate-process
P*(inputs) ==  accumulate (with value and list item input): fst((p input))over list:  inputswith starting value: P)

Lemma: iterate-process_wf
[M,E:Type ⟶ Type].
  (∀P:process(P.M[P];P.E[P]). ∀inputs:M[process(P.M[P];P.E[P])] List.  (P*(inputs) ∈ process(P.M[P];P.E[P]))) supposing 
     (Continuous+(P.E[P]) and 
     Continuous+(P.M[P]))

Lemma: iterate-null-process
[n:Top]. ∀[inputs:Top List].  (null-process(n)*(inputs) null-process(n))

Definition: boot-process
boot-process(f;n) ==
  RecProcess(inr ⋅ ;s,m.case s
   of inl(P) =>
   let Q,e 
   in <inl Q, e>
   inr(x) =>
   case of inl(P) => <inl P, n> inr(x) => <s, n>)

Lemma: boot-process_wf
[M,E:Type ⟶ Type].
  (∀[n:⋂T:Type. E[T]]. ∀[f:⋂T:Type. (M[T] ⟶ (T?))].  (boot-process(f;n) ∈ process(P.M[P];P.E[P]))) supposing 
     (Continuous+(T.E[T]) and 
     Continuous+(T.M[T]))

Definition: virus-process
virus-process(g) ==  fix((λvirus-process,m. <virus-process, virus-process>))

Lemma: virus-process_wf
[M,E:Type ⟶ Type]. ∀[g:⋂T:Type. (T ⟶ E[T])].  (virus-process(g) ∈ process(P.M[P];P.E[P]))

Definition: forkable-process
forkable-process(f;g;P) ==  recprocess(P;s,m.s m;e,m,Q.if then else fi )

Lemma: forkable-process_wf
[M,E:Type ⟶ Type].
  (∀[g:⋂T:Type. (T ⟶ E[T])]. ∀[f:⋂T:Type. (M[T] ⟶ 𝔹)]. ∀[P:process(P.M[P];P.E[P])].
     (forkable-process(f;g;P) ∈ process(P.M[P];P.E[P]))) supposing 
     (Continuous+(T.E[T]) and 
     Continuous+(T.M[T]))

Definition: consensus-state1
consensus-state1(V) ==  Top

Lemma: consensus-state1_wf
[V:Type]. (consensus-state1(V) ∈ Type)

Definition: cs-undecided
UNDECIDED ==  inr ⋅ 

Lemma: cs-undecided_wf
[V:Type]. (UNDECIDED ∈ consensus-state1(V))

Definition: cs-decided
Decided[v] ==  inl v

Lemma: cs-decided_wf
[V:Type]. ∀[v:V].  (Decided[v] ∈ consensus-state1(V))

Definition: consensus-ts1
consensus-ts1(T) ==
  <consensus-state1(T)
  UNDECIDED
  , λx,y. ((x UNDECIDED ∈ consensus-state1(T)) ∧ (∃v:T. (y Decided[v] ∈ consensus-state1(T))))
  , λx.∃v:T. (x Decided[v] ∈ consensus-state1(T))>

Lemma: consensus-ts1_wf
[V:Type]. (consensus-ts1(V) ∈ transition-system{i:l})

Definition: consensus-state2
consensus-state2(T) ==  Top

Lemma: consensus-state2_wf
[V:Type]. (consensus-state2(V) ∈ Type)

Lemma: cs-decided_wf2
[V:Type]. ∀[v:V].  (Decided[v] ∈ consensus-state2(V))

Definition: cs-is-decided
cs-is-decided(x) ==  isl(x)

Lemma: cs-is-decided_wf
[V:Type]. ∀[x:consensus-state2(V)].  (cs-is-decided(x) ∈ 𝔹)

Lemma: assert-cs-is-decided
[V:Type]. ∀x:consensus-state2(V). (↑cs-is-decided(x) ⇐⇒ ∃v:V. (x Decided[v] ∈ consensus-state2(V)))

Definition: cs-ambivalent
AMBIVALENT ==  inr inr ⋅  

Lemma: cs-ambivalent_wf
[V:Type]. (AMBIVALENT ∈ consensus-state2(V))

Definition: cs-predecided
PREDECIDED[v] ==  inr (inl v) 

Lemma: cs-predecided_wf
[V:Type]. ∀[v:V].  (PREDECIDED[v] ∈ consensus-state2(V))

Lemma: consensus-state2-cases
[V:Type]
  ∀x:consensus-state2(V)
    ((x AMBIVALENT ∈ consensus-state2(V))
    ∨ (∃v:V. ((x PREDECIDED[v] ∈ consensus-state2(V)) ∨ (x Decided[v] ∈ consensus-state2(V)))))

Definition: consensus-ts2
consensus-ts2(T) ==
  <consensus-state2(T)
  AMBIVALENT
  , λx,y. (((x AMBIVALENT ∈ consensus-state2(T)) ∧ (∃v:T. (y PREDECIDED[v] ∈ consensus-state2(T))))
         ∨ (∃v:T
             ((x PREDECIDED[v] ∈ consensus-state2(T))
             ∧ ((y Decided[v] ∈ consensus-state2(T)) ∨ (y AMBIVALENT ∈ consensus-state2(T))))))
  , λx.∃v:T. (x Decided[v] ∈ consensus-state2(T))>

Lemma: consensus-ts2_wf
[V:Type]. (consensus-ts2(V) ∈ transition-system{i:l})

Lemma: consensus-refinement1
[V:Type]. ts-refinement(consensus-ts1(V);consensus-ts2(V);λx.if cs-is-decided(x) then else UNDECIDED fi )

Definition: consensus-state3
consensus-state3(T) ==  + 𝔹

Lemma: consensus-state3_wf
[V:Type]. (consensus-state3(V) ∈ Type)

Definition: cs-initial
INITIAL ==  inr inr ff  

Lemma: cs-initial_wf
[V:Type]. (INITIAL ∈ consensus-state3(V))

Lemma: decidable__equal_cs-initial
[V:Type]. ∀x:consensus-state3(V). Dec(x INITIAL ∈ consensus-state3(V))

Definition: cs-withdrawn
WITHDRAWN ==  inr inr tt  

Lemma: cs-withdrawn_wf
[V:Type]. (WITHDRAWN ∈ consensus-state3(V))

Lemma: decidable__equal_cs-withdrawn
[V:Type]. ∀x:consensus-state3(V). Dec(x WITHDRAWN ∈ consensus-state3(V))

Definition: cs-considering
CONSIDERING[v] ==  inr (inl v) 

Lemma: cs-considering_wf
[V:Type]. ∀[v:V].  (CONSIDERING[v] ∈ consensus-state3(V))

Definition: cs-commited
COMMITED[v] ==  inl v

Lemma: cs-commited_wf
[V:Type]. ∀[v:V].  (COMMITED[v] ∈ consensus-state3(V))

Lemma: cs-commited-equal
[V:Type]. ∀[v1,v:V].  uiff(COMMITED[v] COMMITED[v1] ∈ consensus-state3(V);v v1 ∈ V)

Lemma: cs-considering-equal
[V:Type]. ∀[v1,v:V].  uiff(CONSIDERING[v] CONSIDERING[v1] ∈ consensus-state3(V);v v1 ∈ V)

Definition: cs-is-committed
cs-is-committed(x) ==  isl(x)

Lemma: cs-is-committed_wf
[V:Type]. ∀[x:consensus-state3(V)].  (cs-is-committed(x) ∈ 𝔹)

Definition: cs-committed-val
cs-committed-val(x) ==  outl(x)

Lemma: cs-committed-val_wf
[V:Type]. ∀[x:{x:consensus-state3(V)| ↑cs-is-committed(x)} ].  (cs-committed-val(x) ∈ V)

Lemma: assert-cs-is-committed
[V:Type]. ∀x:consensus-state3(V). (↑cs-is-committed(x) ⇐⇒ ∃v:V. (x COMMITED[v] ∈ consensus-state3(V)))

Lemma: cs-is-committed-implies
[V:Type]. ∀[x:consensus-state3(V)].
  COMMITED[cs-committed-val(x)] ∈ consensus-state3(V) supposing ↑cs-is-committed(x)

Definition: cs-is-considering
cs-is-considering(x) ==  case of inl(z) => ff inr(z) => isl(z)

Lemma: cs-is-considering_wf
[V:Type]. ∀[x:consensus-state3(V)].  (cs-is-considering(x) ∈ 𝔹)

Definition: cs-considered-val
cs-considered-val(x) ==  outl(outr(x))

Lemma: cs-considered-val_wf
[V:Type]. ∀[x:{x:consensus-state3(V)| ↑cs-is-considering(x)} ].  (cs-considered-val(x) ∈ V)

Lemma: assert-cs-is-considering
[V:Type]. ∀x:consensus-state3(V). (↑cs-is-considering(x) ⇐⇒ ∃v:V. (x CONSIDERING[v] ∈ consensus-state3(V)))

Lemma: cs-is-considering-implies
[V:Type]. ∀[x:consensus-state3(V)].
  CONSIDERING[cs-considered-val(x)] ∈ consensus-state3(V) supposing ↑cs-is-considering(x)

Lemma: consensus-state3-unequal
[V:Type]
  ((¬(INITIAL WITHDRAWN ∈ consensus-state3(V)))
  ∧ (∀[v:V]
       (((¬(COMMITED[v] INITIAL ∈ consensus-state3(V))) ∧ (CONSIDERING[v] INITIAL ∈ consensus-state3(V))))
       ∧ (COMMITED[v] WITHDRAWN ∈ consensus-state3(V)))
       ∧ (CONSIDERING[v] WITHDRAWN ∈ consensus-state3(V)))
       ∧ (∀[v':V]
            ((¬(CONSIDERING[v] COMMITED[v'] ∈ consensus-state3(V)))
            ∧ (CONSIDERING[v] CONSIDERING[v'] ∈ consensus-state3(V)))
              ∧ (COMMITED[v] COMMITED[v'] ∈ consensus-state3(V))) 
              supposing ¬(v v' ∈ V))))))

Lemma: consensus-state3-cases
[V:Type]
  ∀x:consensus-state3(V)
    (((x INITIAL ∈ consensus-state3(V)) ∨ (x WITHDRAWN ∈ consensus-state3(V)))
    ∨ (∃v:V. ((x CONSIDERING[v] ∈ consensus-state3(V)) ∨ (x COMMITED[v] ∈ consensus-state3(V)))))

Definition: consensus-ts3
consensus-ts3(T) ==
  <consensus-state3(T) List
  []
  , λx,y. ((y (x [INITIAL]) ∈ (consensus-state3(T) List))
         ∨ ((||y|| ||x|| ∈ ℤ)
           ∧ (∃i:ℕ||x||
               ((∀j:ℕ||x||. ((¬(j i ∈ ℤ))  (y[j] x[j] ∈ consensus-state3(T))))
               ∧ (((x[i] INITIAL ∈ consensus-state3(T))
                 ∧ ((y[i] WITHDRAWN ∈ consensus-state3(T))
                   ∨ (∃v:T
                       ((y[i] CONSIDERING[v] ∈ consensus-state3(T))
                       ∧ (∀j:ℕi
                            ((x[j] WITHDRAWN ∈ consensus-state3(T))
                            ∨ (x[j] CONSIDERING[v] ∈ consensus-state3(T))
                            ∨ (x[j] COMMITED[v] ∈ consensus-state3(T))))))))
                 ∨ (∃v:T
                     ((x[i] CONSIDERING[v] ∈ consensus-state3(T))
                     ∧ ((y[i] COMMITED[v] ∈ consensus-state3(T)) ∨ (y[i] WITHDRAWN ∈ consensus-state3(T))))))))))
  , λx.∃v:T. (x [COMMITED[v]] ∈ (consensus-state3(T) List))>

Lemma: consensus-ts3_wf
[V:Type]. (consensus-ts3(V) ∈ transition-system{i:l})

Lemma: consensus-ts3-invariant0
[V:Type]
  ∀L:ts-reachable(consensus-ts3(V)). ∀i:ℕ||L||.
    ∀j:ℕ||L||. (L[j] INITIAL ∈ consensus-state3(V)) ∨ (L[j] WITHDRAWN ∈ consensus-state3(V)) supposing i < 
    supposing L[i] INITIAL ∈ consensus-state3(V)

Lemma: consensus-ts3-invariant1
[V:Type]. ∀[L:ts-reachable(consensus-ts3(V))]. ∀[v:V].
  ∀[v':V]. v' v ∈ supposing (CONSIDERING[v'] ∈ L) ∨ (COMMITED[v'] ∈ L) 
  supposing (CONSIDERING[v] ∈ L) ∨ (COMMITED[v] ∈ L)

Definition: cs-ref-map3
cs-ref-map3(L) ==
  let cmtd filter(λx.cs-is-committed(x);L) in
   let consd filter(λx.cs-is-considering(x);L) in
   if null(cmtd)
   then if null(consd) then AMBIVALENT else PREDECIDED[cs-considered-val(hd(consd))] fi 
   else Decided[cs-committed-val(hd(cmtd))]
   fi 

Lemma: cs-ref-map3_wf
[V:Type]. ∀[L:consensus-state3(V) List].  (cs-ref-map3(L) ∈ consensus-state2(V))

Lemma: cs-ref-map3-decided
[V:Type]
  ∀L:ts-reachable(consensus-ts3(V)). ∀v:V.  ((COMMITED[v] ∈ L) ⇐⇒ cs-ref-map3(L) Decided[v] ∈ consensus-state2(V))

Lemma: cs-ref-map3-predecided
[V:Type]
  ∀L:ts-reachable(consensus-ts3(V)). ∀v:V.
    ((∀v':V. (COMMITED[v'] ∈ L))) ∧ (CONSIDERING[v] ∈ L) ⇐⇒ cs-ref-map3(L) PREDECIDED[v] ∈ consensus-state2(V))

Lemma: cs-ref-map3-ambivalent
[V:Type]. ∀[L:ts-reachable(consensus-ts3(V))].
  uiff((∀[v:V]. (COMMITED[v] ∈ L))) ∧ (∀[v:V]. (CONSIDERING[v] ∈ L)));cs-ref-map3(L)
  AMBIVALENT
  ∈ consensus-state2(V))

Lemma: consensus-refinement2
[V:Type]. ts-refinement(consensus-ts2(V);consensus-ts3(V);λL.cs-ref-map3(L))

Definition: consensus-state4
ConsensusState ==  {a:Id| (a ∈ A)}  ⟶ (ℤ × j:ℤ fp-> V)

Lemma: consensus-state4_wf
[A:Id List]. ∀[V:Type].  (ConsensusState ∈ Type)

Lemma: consensus-state4-subtype
[A:Id List]. ∀[V1,V2:Type].  ConsensusState ⊆ConsensusState supposing V1 ⊆V2

Definition: cs-inning
Inning(s;a) ==  fst((s a))

Lemma: cs-inning_wf
[V:Type]. ∀[A:Id List]. ∀[s:ConsensusState]. ∀[a:{a:Id| (a ∈ A)} ].  (Inning(s;a) ∈ ℤ)

Definition: cs-estimate
Estimate(s;a) ==  snd((s a))

Lemma: cs-estimate_wf
[V:Type]. ∀[A:Id List]. ∀[s:ConsensusState]. ∀[a:{a:Id| (a ∈ A)} ].  (Estimate(s;a) ∈ i:ℤ fp-> V)

Definition: cs-archive-blocked
in state s, ws' blocks ws from archiving in inning ==
  ∃j:ℤ
   (((0 ≤ j) ∧ j < i)
   ∧ (∃v':V
       ((¬(v' v ∈ V))
       ∧ (∀b:{a:Id| (a ∈ A)} 
            (((b ∈ ws) ∧ (b ∈ ws'))
             ((↑j ∈ dom(Estimate(s;b)))
               ∧ (Estimate(s;b)(j) v' ∈ V)
               ∧ (∀k:ℤ(((j < k ∧ k < i) ∧ (↑k ∈ dom(Estimate(s;b))))  (Estimate(s;b)(k) v' ∈ V)))))))))

Lemma: cs-archive-blocked_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[s:ConsensusState]. ∀[i:ℤ]. ∀[v:V].
[ws,ws':{a:Id| (a ∈ A)}  List].
  (in state s, ws' blocks ws from archiving in inning i ∈ ℙ)

Definition: cs-precondition
state may consider in inning ==
  ∃ws:{a:Id| (a ∈ A)}  List
   ((ws ∈ W)
   ∧ (∀b:{a:Id| (a ∈ A)} ((b ∈ ws)  (i ≤ Inning(s;b))))
   ∧ (∀ws':{a:Id| (a ∈ A)}  List. ((ws' ∈ W)  in state s, ws' blocks ws from archiving in inning i))))

Lemma: cs-precondition_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[s:ConsensusState]. ∀[i:ℤ]. ∀[v:V].
  (state may consider in inning i ∈ ℙ)

Definition: consensus-rel
CR[x,y] ==
  ∃a:{a:Id| (a ∈ A)} 
   ((∀b:{a:Id| (a ∈ A)} 
       ((¬(b a ∈ Id))  ((Inning(y;b) Inning(x;b) ∈ ℤ) ∧ (Estimate(y;b) Estimate(x;b) ∈ i:ℤ fp-> V))))
   ∧ (((Inning(y;a) (Inning(x;a) 1) ∈ ℤ) ∧ (Estimate(y;a) Estimate(x;a) ∈ i:ℤ fp-> V))
     ∨ ((Inning(y;a) Inning(x;a) ∈ ℤ)
       ∧ (Inning(x;a) ∈ fpf-domain(Estimate(x;a))))
       ∧ (∃v:V
           (state may consider in inning Inning(x;a)
           ∧ (Estimate(y;a) Estimate(x;a) ⊕ Inning(x;a) v ∈ i:ℤ fp-> V))))))

Lemma: consensus-rel_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[x,y:ConsensusState].  (CR[x,y] ∈ ℙ)

Definition: consensus-rel-mod
CR(in ws)[x, y]  ==
  ∃a:{a:Id| (a ∈ A)} 
   ((a ∈ ws)
   ∧ (∀b:{a:Id| (a ∈ A)} 
        ((¬(b a ∈ Id))  ((Inning(y;b) Inning(x;b) ∈ ℤ) ∧ (Estimate(y;b) Estimate(x;b) ∈ i:ℤ fp-> V))))
   ∧ (((Inning(y;a) (Inning(x;a) 1) ∈ ℤ) ∧ (Estimate(y;a) Estimate(x;a) ∈ i:ℤ fp-> V))
     ∨ ((Inning(y;a) Inning(x;a) ∈ ℤ)
       ∧ (Inning(x;a) ∈ fpf-domain(Estimate(x;a))))
       ∧ (∃v:V
           (state may consider in inning Inning(x;a)
           ∧ (Estimate(y;a) Estimate(x;a) ⊕ Inning(x;a) v ∈ i:ℤ fp-> V))))))

Lemma: consensus-rel-mod_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[ws:{a:Id| (a ∈ A)}  List]. ∀[x,y:ConsensusState].
  (CR(in ws)[x, y]  ∈ ℙ)

Definition: consensus-ts4
consensus-ts4(V;A;W) ==
  <ConsensusState
  , λa.<-1, ⊗>
  , λx,y. CR[x,y]
  , λx.∃v:V. ∀a:{a:Id| (a ∈ A)} ((Inning(x;a) 0 ∈ ℤ) ∧ (Estimate(x;a) v ∈ i:ℤ fp-> V))>

Lemma: consensus-ts4_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List].  (consensus-ts4(V;A;W) ∈ transition-system{i:l})

Lemma: consensus-ts4-inning-rel
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[a:{a:Id| (a ∈ A)} ].
  ts-stable-rel(consensus-ts4(V;A;W);x,y.Inning(x;a) ≤ Inning(y;a))

Lemma: consensus-ts4-estimate-rel
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[a:{a:Id| (a ∈ A)} ].
  ts-stable-rel(consensus-ts4(V;A;W);x,y.Estimate(x;a) ⊆ Estimate(y;a))

Lemma: consensus-ts4-estimate-domain
V:Type. ∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀a:{a:Id| (a ∈ A)} . ∀x:ts-reachable(consensus-ts4(V;A;W)). ∀i:ℤ.
  ((i ∈ fpf-domain(Estimate(x;a)))  (i ≤ Inning(x;a)))

Definition: cs-not-completed
in state s, has not completed inning ==  (Inning(s;a) ≤ i) ∧ (i ∈ fpf-domain(Estimate(s;a))))

Lemma: cs-not-completed_wf
[V:Type]. ∀[A:Id List]. ∀[s:ConsensusState]. ∀[a:{a:Id| (a ∈ A)} ]. ∀[i:ℤ].
  (in state s, has not completed inning i ∈ ℙ)

Lemma: decidable__cs-not-completed
[V:Type]. ∀A:Id List. ∀s:ConsensusState. ∀a:{a:Id| (a ∈ A)} . ∀i:ℤ.  Dec(in state s, has not completed inning i)

Definition: cs-archived
by state s, archived in inning ==  (i ∈ fpf-domain(Estimate(s;a))) ∧ (Estimate(s;a)(i) v ∈ V)

Lemma: cs-archived_wf
[V:Type]. ∀[A:Id List]. ∀[s:ConsensusState]. ∀[a:{a:Id| (a ∈ A)} ]. ∀[i:ℤ]. ∀[v:V].
  (by state s, archived in inning i ∈ ℙ)

Lemma: decidable__cs-archived
[V:Type]
  ∀A:Id List. ∀s:ConsensusState. ∀a:{a:Id| (a ∈ A)} . ∀i:ℤ. ∀v:V.
    ((∀v,v':V.  Dec(v v' ∈ V))  Dec(by state s, archived in inning i))

Definition: cs-passed
by state s, passed inning without archiving value ==  i < Inning(s;a) ∧ (i ∈ fpf-domain(Estimate(s;a))))

Lemma: cs-passed_wf
[V:Type]. ∀[A:Id List]. ∀[s:ConsensusState]. ∀[a:{a:Id| (a ∈ A)} ]. ∀[i:ℤ].
  (by state s, passed inning without archiving value ∈ ℙ)

Lemma: decidable__cs-passed
[V:Type]
  ∀A:Id List. ∀s:ConsensusState. ∀a:{a:Id| (a ∈ A)} . ∀i:ℤ.  Dec(by state s, passed inning without archiving value\000C)

Lemma: consensus-state4-cases
[V:Type]
  ∀A:Id List. ∀s:ConsensusState. ∀a:{a:Id| (a ∈ A)} . ∀i:ℤ.
    (by state s, passed inning without archiving value
    ∨ in state s, has not completed inning i
    ∨ (∃v:V. by state s, archived in inning i))

Lemma: consensus-state4-exclusive-cases
[V:Type]
  ∀A:Id List. ∀s:ConsensusState. ∀a:{a:Id| (a ∈ A)} . ∀i:ℤ.
    ((by state s, passed inning without archiving value
     ∧ in state s, has not completed inning i)
     ∧ (∀v:V. by state s, archived in inning i)))
    ∨ (in state s, has not completed inning i
      ∧ by state s, passed inning without archiving value)
      ∧ (∀v:V. by state s, archived in inning i)))
    ∨ (∃v:V
        (by state s, archived in inning i
        ∧ by state s, passed inning without archiving value)
        ∧ in state s, has not completed inning i)
        ∧ (∀v':V. ¬by state s, archived v' in inning supposing ¬(v' v ∈ V)))))

Lemma: consensus-ts4-archived-stable
[V:Type]
  ∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀a:{a:Id| (a ∈ A)} . ∀i:ℤ. ∀v:V.
    ts-stable(consensus-ts4(V;A;W);s.by state s, archived in inning i)

Lemma: consensus-ts4-passed-stable
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[a:{a:Id| (a ∈ A)} ]. ∀[i:ℤ].
  ts-stable(consensus-ts4(V;A;W);s.by state s, passed inning without archiving value)

Definition: cs-inning-committed
in state s, inning has committed ==
  ∃ws:{a:Id| (a ∈ A)}  List. ((ws ∈ W) ∧ (∀a:{a:Id| (a ∈ A)} ((a ∈ ws)  by state s, archived in inning i)))

Lemma: cs-inning-committed_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[s:ConsensusState]. ∀[i:ℤ]. ∀[v:V].
  (in state s, inning has committed v ∈ ℙ)

Lemma: consensus-ts4-inning-committed-stable
[V:Type]
  ∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀v:V. ∀i:ℤ.
    ts-stable(consensus-ts4(V;A;W);s.in state s, inning has committed v)

Lemma: decidable__cs-inning-committed
[V:Type]
  ((∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀s:ConsensusState. ∀i:ℤ. ∀v:V.
        Dec(in state s, inning has committed v)))

Definition: cs-inning-committable
in state s, inning could commit v  ==
  ∃ws:{a:Id| (a ∈ A)}  List
   ((ws ∈ W)
   ∧ (∀a:{a:Id| (a ∈ A)} 
        ((a ∈ ws)  (by state s, archived in inning i ∨ in state s, has not completed inning i))))

Lemma: cs-inning-committable_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[s:ConsensusState]. ∀[i:ℤ]. ∀[v:V].
  (in state s, inning could commit v  ∈ ℙ)

Lemma: cs-inning-committed-committable
[V:Type]
  ∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀s:ConsensusState. ∀i:ℤ. ∀v:V.
    (in state s, inning has committed  in state s, inning could commit )

Lemma: decidable__cs-inning-committable
[V:Type]
  ((∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀s:ConsensusState. ∀i:ℤ. ∀v:V.
        Dec(in state s, inning could commit )))

Definition: one-intersection
one-intersection(A;W) ==  (∀ws∈W.∃a:{a:Id| (a ∈ A)} (a ∈ ws))

Lemma: one-intersection_wf
[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List].  (one-intersection(A;W) ∈ ℙ)

Definition: two-intersection
two-intersection(A;W) ==  (∀ws1∈W.(∀ws2∈W.∃a:{a:Id| (a ∈ A)} ((a ∈ ws1) ∧ (a ∈ ws2))))

Lemma: two-intersection_wf
[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List].  (two-intersection(A;W) ∈ ℙ)

Definition: three-intersection
three-intersection(A;W) ==  (∀ws1∈W.(∀ws2∈W.(∀ws3∈W.∃a:{a:Id| (a ∈ A)} ((a ∈ ws1) ∧ (a ∈ ws2) ∧ (a ∈ ws3)))))

Lemma: three-intersection_wf
[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List].  (three-intersection(A;W) ∈ ℙ)

Lemma: three-intersection-two-intersection
A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.  (three-intersection(A;W)  two-intersection(A;W))

Lemma: two-intersection-one-intersection
A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.  (two-intersection(A;W)  one-intersection(A;W))

Lemma: three-intersecting-wait-set
t:ℕ. ∀A:Id List.
  ({a:Id| (a ∈ A)}  ~ ℕ(3 t) 1
   (∀W:{a:Id| (a ∈ A)}  List List
        ((∀ws:{a:Id| (a ∈ A)}  List. ((ws ∈ W) ⇐⇒ (||ws|| ((2 t) 1) ∈ ℤ) ∧ no_repeats({a:Id| (a ∈ A)} ;ws)))
         three-intersection(A;W))))

Lemma: two-intersecting-wait-set
t:ℕ. ∀A:Id List.
  ({a:Id| (a ∈ A)}  ~ ℕ(2 t) 1
   (∀W:{a:Id| (a ∈ A)}  List List
        ((∀ws:{a:Id| (a ∈ A)}  List. ((ws ∈ W) ⇐⇒ (||ws|| (t 1) ∈ ℤ) ∧ no_repeats({a:Id| (a ∈ A)} ;ws)))
         two-intersection(A;W))))

Lemma: three-intersecting-wait-set-exists
t:ℕ. ∀A:Id List.
  (∃W:{a:Id| (a ∈ A)}  List List
    ((∀ws:{a:Id| (a ∈ A)}  List. ((ws ∈ W) ⇐⇒ (||ws|| ((2 t) 1) ∈ ℤ) ∧ no_repeats({a:Id| (a ∈ A)} ;ws)))
    ∧ three-intersection(A;W))) supposing 
     (no_repeats(Id;A) and 
     (||A|| ((3 t) 1) ∈ ℤ))

Lemma: two-intersecting-wait-set-exists
t:ℕ. ∀A:Id List.
  (∃W:{a:Id| (a ∈ A)}  List List
    ((∀ws:{a:Id| (a ∈ A)}  List. ((ws ∈ W) ⇐⇒ (||ws|| (t 1) ∈ ℤ) ∧ no_repeats({a:Id| (a ∈ A)} ;ws)))
    ∧ two-intersection(A;W))) supposing 
     (no_repeats(Id;A) and 
     (||A|| ((2 t) 1) ∈ ℤ))

Lemma: two-intersecting-wait-set-exists'
t:ℕ. ∀A:Id List.
  (∃W:Id List List
    ((∀ws:Id List. ((ws ∈ W) ⇐⇒ (||ws|| (t 1) ∈ ℤ) ∧ no_repeats(Id;ws) ∧ (∀x∈ws.(x ∈ A))))
    ∧ (∀ws1∈W.(∀ws2∈W.∃a:Id. ((a ∈ ws1) ∧ (a ∈ ws2)))))) supposing 
     (no_repeats(Id;A) and 
     (||A|| ((2 t) 1) ∈ ℤ))

Lemma: cs-archived-listable
[V:Type]
  ∀A:Id List. ∀s:ConsensusState.
    ∃L:V List
     ∀b:{a:Id| (a ∈ A)} . ∀v:V. ∀j:ℤ.  ((v ∈ L)) supposing ((Estimate(s;b)(j) v ∈ V) and (↑j ∈ dom(Estimate(s;b))))

Lemma: decidable__cs-archive-blocked
[V:Type]
  ((∀v1,v2:V.  Dec(v1 v2 ∈ V))
   (∃v,v':V. (v v' ∈ V)))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀ws,ws':{a:Id| (a ∈ A)}  List. ∀s:ConsensusState. ∀i:ℤ. ∀v:V.
        Dec(in state s, ws' blocks ws from archiving in inning i)))

Lemma: decidable__cs-precondition
[V:Type]
  ((∀v1,v2:V.  Dec(v1 v2 ∈ V))
   (∃v,v':V. (v v' ∈ V)))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀s:ConsensusState. ∀i:ℤ. ∀v:V.
        Dec(state may consider in inning i)))

Lemma: cs-inning-committed-single
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[s:ConsensusState]. ∀[i:ℤ]. ∀[v,v2:V].
  (v v2 ∈ V) supposing 
     (in state s, inning has committed v2 and 
     in state s, inning could commit v  and 
     two-intersection(A;W))

Lemma: cs-inning-committed-single-stable
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[s,s2:ConsensusState].
  ∀[i:ℤ]. ∀[v,v2:V].
    (v v2 ∈ V) supposing 
       (in state s, inning has committed v2 and 
       in state s2, inning could commit v  and 
       two-intersection(A;W)) 
  supposing ts-rel(consensus-ts4(V;A;W)) s2

Lemma: cs-inning-committed-some1
[V:Type]
  ((∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (one-intersection(A;W)
         (∀s:ConsensusState. ∀i:ℤ.
              ∃L:V List
               (∃v:V. in state s, inning has committed ⇐⇒ (∃v∈L. in state s, inning has committed v))))))

Lemma: decidable__cs-inning-committed-some
[V:Type]
  ((∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (one-intersection(A;W)  (∀s:ConsensusState. ∀i:ℤ.  Dec(∃v:V. in state s, inning has committed v)))))

Lemma: cs-inning-committable-some2
[V:Type]
  ((∃v,v':V. (v v' ∈ V)))
   (∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (one-intersection(A;W)
         (∀s:ConsensusState. ∀i:ℤ.
              ∃L:V List
               ∀v:V
                 (in state s, inning could commit 
                 ⇐⇒ (in state s, inning could commit v  ∧ (v ∈ L))
                     ∨ (∃ws∈W. ∀a:{a:Id| (a ∈ A)} ((a ∈ ws)  in state s, has not completed inning i)))))))

Lemma: cs-inning-committable-some1
[V:Type]
  ((∃v,v':V. (v v' ∈ V)))
   (∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (one-intersection(A;W)
         (∀s:ConsensusState. ∀i:ℤ.
              ∃L:V List
               (∃v:V. in state s, inning could commit 
               ⇐⇒ (∃v∈L. in state s, inning could commit )
                   ∨ (∃ws∈W. ∀a:{a:Id| (a ∈ A)} ((a ∈ ws)  in state s, has not completed inning i)))))))

Lemma: decidable__cs-inning-committable-some
[V:Type]
  ((∃v,v':V. (v v' ∈ V)))
   (∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (one-intersection(A;W)  (∀s:ConsensusState. ∀i:ℤ.  Dec(∃v:V. in state s, inning could commit )))))

Lemma: decidable__cs-inning-committable-another
[V:Type]
  ((∃v,v':V. (v v' ∈ V)))
   (∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (one-intersection(A;W)
         (∀s:ConsensusState. ∀i:ℤ. ∀v':V.  Dec(∃v:V. ((¬(v v' ∈ V)) ∧ in state s, inning could commit ))))))

Lemma: decidable__cs-inning-two-committable
[V:Type]
  ((∃v,v':V. (v v' ∈ V)))
   (∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (one-intersection(A;W)
         (∀s:ConsensusState. ∀i:ℤ.
              Dec(∃v,v':V
                   ((¬(v v' ∈ V)) ∧ in state s, inning could commit v  ∧ in state s, inning could commit v' ))))))

Lemma: consensus-ts4-ref-map1
[V:Type]
  ((∃v,v':V. (v v' ∈ V)))
   (∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (two-intersection(A;W)
         {∀s:ConsensusState. ∀i:ℤ.
              ∃x:consensus-state3(V)
               ((x INITIAL ∈ consensus-state3(V)
                ⇐⇒ ∃v,v':V
                     ((¬(v v' ∈ V)) ∧ in state s, inning could commit v  ∧ in state s, inning could commit v' ))
               ∧ (x WITHDRAWN ∈ consensus-state3(V) ⇐⇒ ¬(∃v:V. in state s, inning could commit ))
               ∧ (∀v:V
                    ((x COMMITED[v] ∈ consensus-state3(V) ⇐⇒ in state s, inning has committed v)
                    ∧ (x CONSIDERING[v] ∈ consensus-state3(V)
                      ⇐⇒ in state s, inning could commit 
                          ∧ in state s, inning has committed v)
                          ∧ (∀v':V. (in state s, inning could commit v'   (v' v ∈ V)))))))})))

Definition: cs-ref-map-constraints
cs-ref-map-constraints(V;A;W;f) ==
  ∀s:ConsensusState. ∀i:ℕ.
    ((i < ||f s|| ⇐⇒ ∃a:{a:Id| (a ∈ A)} (i ≤ Inning(s;a)))
    ∧ (i < ||f s||
       ((f s[i] INITIAL ∈ consensus-state3(V)
          ⇐⇒ ∃v,v':V. ((¬(v v' ∈ V)) ∧ in state s, inning could commit v  ∧ in state s, inning could commit v' ))
         ∧ (f s[i] WITHDRAWN ∈ consensus-state3(V) ⇐⇒ ¬(∃v:V. in state s, inning could commit ))
         ∧ (∀v:V
              ((f s[i] COMMITED[v] ∈ consensus-state3(V) ⇐⇒ in state s, inning has committed v)
              ∧ (f s[i] CONSIDERING[v] ∈ consensus-state3(V)
                ⇐⇒ in state s, inning could commit 
                    ∧ in state s, inning has committed v)
                    ∧ (∀v':V. (in state s, inning could commit v'   (v' v ∈ V)))))))))

Lemma: cs-ref-map-constraints_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[f:ConsensusState ⟶ (consensus-state3(V) List)].
  (cs-ref-map-constraints(V;A;W;f) ∈ ℙ)

Lemma: cs-ref-map-equal
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[f:ConsensusState ⟶ (consensus-state3(V) List)].
  ∀[x,y:ConsensusState]. ∀[i:ℕ||f x||].
    (f x[i] y[i] ∈ consensus-state3(V)) supposing 
       ((∀v:V
           ((in state x, inning could commit v  ⇐⇒ in state y, inning could commit )
           ∧ (in state x, inning has committed ⇐⇒ in state y, inning has committed v))) and 
       i < ||f y||) 
  supposing cs-ref-map-constraints(V;A;W;f)

Lemma: consensus-ts4-ref-map
[V:Type]
  ((∃v,v':V. (v v' ∈ V)))
   (∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (two-intersection(A;W)  (∃f:ConsensusState ⟶ (consensus-state3(V) List). cs-ref-map-constraints(V;A;W;f)))))

Lemma: committed-inning0-reachable
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List].
  ∀[v:V]. a.<0, v> ∈ ts-reachable(consensus-ts4(V;A;W))) supposing ||W|| ≥ 

Lemma: cs-inning-committable-step
V:Type
  ((∀v,v':V.  Dec(v v' ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀x,y:ts-reachable(consensus-ts4(V;A;W)). ∀i:ℕ. ∀v:V.
        ((x ts-rel(consensus-ts4(V;A;W)) y)
         in state y, inning could commit 
         in state x, inning could commit )))

Lemma: cs-ref-map-unchanged
[V:Type]
  ((∀v1,v2:V.  Dec(v1 v2 ∈ V))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (two-intersection(A;W)
         (∀f:ConsensusState ⟶ (consensus-state3(V) List)
              (cs-ref-map-constraints(V;A;W;f)
               (∀x,y:ts-reachable(consensus-ts4(V;A;W)).
                    ((x ts-rel(consensus-ts4(V;A;W)) y)
                     (∀i:ℕ
                          ((∀v:V. (in state x, inning could commit v   in state y, inning could commit ))
                              ((f y[i] x[i] ∈ consensus-state3(V))
                                ∨ (∃v:V
                                    ((f y[i] COMMITED[v] ∈ consensus-state3(V))
                                    ∧ (f x[i] CONSIDERING[v] ∈ consensus-state3(V)))))) supposing 
                             (i < ||f y|| and 
                             i < ||f x||)))))))))

Lemma: consensus-ts4-archived-invariant
[V:Type]
  ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[x:ts-reachable(consensus-ts4(V;A;W))]. ∀[i:ℤ]. ∀[v:V]. ∀[a:{a:Id| 
                                                                                                              (a ∈ A)} ]\000C.
    ∀[j:ℕi]. ∀[v':V].  v' v ∈ supposing in state x, inning could commit v'  
    supposing by state x, archived in inning 
  supposing ∀v1,v2:V.  Dec(v1 v2 ∈ V)

Lemma: cs-ref-map-changed
[V:Type]
  ((∀v1,v2:V.  Dec(v1 v2 ∈ V))
   {∃v,v':V. (v v' ∈ V))}
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (two-intersection(A;W)
         (∀f:ConsensusState ⟶ (consensus-state3(V) List)
              (cs-ref-map-constraints(V;A;W;f)
               (∀x,y:ts-reachable(consensus-ts4(V;A;W)).
                    ((x ts-rel(consensus-ts4(V;A;W)) y)
                     (∀i:ℕ
                          (∀v:V
                             ((in state x, inning could commit v  ∧ in state y, inning could commit ))
                              ((f y[i] WITHDRAWN ∈ consensus-state3(V))
                                ∨ ((f x[i] INITIAL ∈ consensus-state3(V))
                                  ∧ ((f y[i] INITIAL ∈ consensus-state3(V))
                                    ∨ (∃v':V
                                        ((∀j:ℕi. (f x[j] INITIAL ∈ consensus-state3(V))))
                                        ∧ ((f y[i] CONSIDERING[v'] ∈ consensus-state3(V))
                                          ∨ (f y[i] COMMITED[v'] ∈ consensus-state3(V)))
                                        ∧ (∀j:ℕi. ∀v'':V.
                                             (((f x[j] CONSIDERING[v''] ∈ consensus-state3(V))
                                             ∨ (f x[j] COMMITED[v''] ∈ consensus-state3(V)))
                                              (v'' v' ∈ V)))))))))) supposing 
                             (i < ||f y|| and 
                             i < ||f x||)))))))))

Lemma: cs-ref-map-step
[V:Type]
  ({∃v1,v2:V. (v1 v2 ∈ V))}
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        ∀f:ConsensusState ⟶ (consensus-state3(V) List)
          (cs-ref-map-constraints(V;A;W;f)
           (∀x,y:ts-reachable(consensus-ts4(V;A;W)).
                ((x ts-rel(consensus-ts4(V;A;W)) y)
                 {(||f x|| ≤ ||f y||)
                   ∧ (∃i:ℤ
                       ((∀j:ℕ||f x||. y[j] x[j] ∈ consensus-state3(V) supposing ¬(j i ∈ ℤ))
                       ∧ (||f y|| (||f x|| 1) ∈ ℤ) ∧ (f y[||f x||] INITIAL ∈ consensus-state3(V)) 
                         supposing ||f x|| < ||f y||))}))) 
        supposing ||W|| ≥ ))

Lemma: decidable__cs-committed-change
[V:Type]
  ((∃v,v':V. (v v' ∈ V)))
   (∀v,v':V.  Dec(v v' ∈ V))
   (∀L:V List. Dec(∃v:V. (v ∈ L))))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (one-intersection(A;W)
         (∀i:ℤ. ∀x,y:ConsensusState.
              Dec(∃v:V. (in state x, inning could commit v  ∧ in state y, inning could commit )))))))

Lemma: consensus-refinement3
[V:Type]
  ((∀v1,v2:V.  Dec(v1 v2 ∈ V))
   {∃v,v':V. (v v' ∈ V))}
   (∀L:V List. Dec(∃v:V. (v ∈ L))))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        two-intersection(A;W)
         (∀f:ConsensusState ⟶ (consensus-state3(V) List)
              (cs-ref-map-constraints(V;A;W;f)  ts-refinement(consensus-ts3(V);consensus-ts4(V;A;W);f))) 
        supposing ||W|| ≥ ))

Lemma: consensus-safety1
V:Type
  ((∀v1,v2:V.  Dec(v1 v2 ∈ V))
   {∃v,v':V. (v v' ∈ V))}
   (∀L:V List. Dec(∃v:V. (v ∈ L))))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        ((||W|| ≥ )
         two-intersection(A;W)
         (∃f:ConsensusState ⟶ consensus-state1(V)
             ((∀v:V. ∀s:ts-reachable(consensus-ts4(V;A;W)).
                 ((f s) Decided[v] ∈ consensus-state1(V) ⇐⇒ ∃i:ℕin state s, inning has committed v))
             ∧ ts-refinement(consensus-ts1(V);consensus-ts4(V;A;W);f))))))

Lemma: consensus-safety
V:Type
  ((∀v1,v2:V.  Dec(v1 v2 ∈ V))
   {∃v,v':V. (v v' ∈ V))}
   (∀L:V List. Dec(∃v:V. (v ∈ L))))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        ((||W|| ≥ )
         two-intersection(A;W)
         (∀s1,s2:ts-reachable(consensus-ts4(V;A;W)).
              ((s1 (ts-rel(consensus-ts4(V;A;W))^*) s2)
               (∀v1,v2:V.
                    ((∃i:ℕin state s1, inning has committed v1)
                     (∃j:ℕin state s2, inning has committed v2)
                     (v1 v2 ∈ V))))))))

Lemma: fresh-inning-reachable
[V:Type]
  ∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀ws:{a:Id| (a ∈ A)}  List. ∀x:ConsensusState. ∀i:ℤ.
    ((ws ∈ W)
     ((λx,y. CR(in ws)[x, y] )^*) a.<if a ∈b ws then else Inning(x;a) fi Estimate(x;a)>
       supposing (∀a∈ws.Inning(x;a) < i))

Lemma: consensus-reachable
[V:Type]
  ((∀v1,v2:V.  Dec(v1 v2 ∈ V))
   {∃v,v':V. (v v' ∈ V))}
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        (three-intersection(A;W)
         (∀ws∈W.∀x:ts-reachable(consensus-ts4(V;A;W))
                    ∃y:ConsensusState
                     ((x ((λx,y. CR(in ws)[x, y] )^*) y) ∧ (∃v:V. ∃i:ℤin state y, inning has committed v))))))

Definition: consensus-state5
Knowledge(ConsensusState) ==  {a:Id| (a ∈ A)}  ⟶ b:Id fp-> ℤ × (ℤ × Top)

Definition: cs-knowledge-precondition
may consider in inning based on knowledge (s) ==
  (∃ws:{a:Id| (a ∈ A)}  List
    ((ws ∈ W)
    ∧ (∀b:{a:Id| (a ∈ A)} ((b ∈ ws)  ((↑b ∈ dom(s)) ∧ (i (fst(s(b))) ∈ ℤ))))
    ∧ (∀ws':{a:Id| (a ∈ A)}  List
         ((ws' ∈ W)
          (∃b:{a:Id| (a ∈ A)} ((b ∈ ws) ∧ (b ∈ ws') ∧ ((↑isl(snd(s(b))))  ((snd(outl(snd(s(b))))) v ∈ V))))))))
  ∨ (∃b:{a:Id| (a ∈ A)} 
      ((↑b ∈ dom(s))
      ∧ let j,z s(b) 
        in case of inl(p) => let j',v' in (j' i ∈ ℤ) ∧ (v' v ∈ V) inr(x) => False))

Lemma: cs-knowledge-precondition_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[i:ℤ]. ∀[v:V]. ∀[s:b:Id fp-> ℤ × (ℤ × Top)].
  (may consider in inning based on knowledge (s) ∈ ℙ)

Lemma: consensus-state5_wf
[V:Type]. ∀[A:Id List].  (Knowledge(ConsensusState) ∈ 𝕌{[1 0]})

Definition: cs-knowledge
Knowledge(x;a) ==  a

Lemma: cs-knowledge_wf
[V:Type]. ∀[A:Id List]. ∀[a:{a:Id| (a ∈ A)} ]. ∀[x:Knowledge(ConsensusState)].
  (Knowledge(x;a) ∈ b:Id fp-> ℤ × (ℤ × Top))

Definition: consensus-rel-knowledge-inning-step
consensus-rel-knowledge-inning-step(V;A;W;x1;x2;y1;y2;a) ==
  (Inning(y1;a) (Inning(x1;a) 1) ∈ ℤ)
  ∧ (Estimate(y1;a) Estimate(x1;a) ∈ i:ℤ fp-> V)
  ∧ (Knowledge(y2;a) Knowledge(x2;a) ∈ b:Id fp-> ℤ × (ℤ × Top))

Lemma: consensus-rel-knowledge-inning-step_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[x1,y1:ConsensusState]. ∀[x2,y2:Knowledge(ConsensusState)].
[a:{a:Id| (a ∈ A)} ].
  (consensus-rel-knowledge-inning-step(V;A;W;x1;x2;y1;y2;a) ∈ ℙ)

Definition: consensus-rel-knowledge-archive-step
consensus-rel-knowledge-archive-step(V;A;W;x1;x2;y1;y2;a) ==
  ((Inning(y1;a) Inning(x1;a) ∈ ℤ) ∧ (Knowledge(y2;a) Knowledge(x2;a) ∈ b:Id fp-> ℤ × (ℤ × Top)))
  ∧ (Inning(x1;a) ∈ fpf-domain(Estimate(x1;a))))
  ∧ (∃v:V
      (may consider in inning Inning(x1;a) based on knowledge (Knowledge(x2;a))
      ∧ (Estimate(y1;a) Estimate(x1;a) ⊕ Inning(x1;a) v ∈ i:ℤ fp-> V)))

Lemma: consensus-rel-knowledge-archive-step_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[x1,y1:ConsensusState]. ∀[x2,y2:Knowledge(ConsensusState)].
[a:{a:Id| (a ∈ A)} ].
  (consensus-rel-knowledge-archive-step(V;A;W;x1;x2;y1;y2;a) ∈ ℙ)

Definition: consensus-rel-add-knowledge-step
consensus-rel-add-knowledge-step(V;A;W;x1;x2;y1;y2;a) ==
  (Inning(y1;a) Inning(x1;a) ∈ ℤ)
  ∧ (Estimate(y1;a) Estimate(x1;a) ∈ i:ℤ fp-> V)
  ∧ (∃b:{a:Id| (a ∈ A)} 
      ∃i:ℤ
       ((i ≤ Inning(x1;b))
       ∧ (((∀j:ℤ(j <  (¬↑j ∈ dom(Estimate(x1;b)))))
         ∧ (Knowledge(y2;a) : <i, inr ⋅ > ⊕ Knowledge(x2;a) ∈ b:Id fp-> ℤ × (ℤ × Top)))
         ∨ (∃j:ℤ
             (j < i
             ∧ (↑j ∈ dom(Estimate(x1;b)))
             ∧ (∀k:ℤ(j <  k <  (¬↑k ∈ dom(Estimate(x1;b)))))
             ∧ (Knowledge(y2;a) : <i, inl <j, Estimate(x1;b)(j)>> ⊕ Knowledge(x2;a) ∈ b:Id fp-> ℤ × (ℤ × Top))))\000C)))

Lemma: consensus-rel-add-knowledge-step_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[x1,y1:ConsensusState]. ∀[x2,y2:Knowledge(ConsensusState)].
[a:{a:Id| (a ∈ A)} ].
  (consensus-rel-add-knowledge-step(V;A;W;x1;x2;y1;y2;a) ∈ ℙ)

Definition: consensus-rel-knowledge-step
consensus-rel-knowledge-step(V;A;W;x1;x2;y1;y2;a) ==
  (∀b:{a:Id| (a ∈ A)} 
     ((¬(b a ∈ Id))
      ((Inning(y1;b) Inning(x1;b) ∈ ℤ)
        ∧ (Estimate(y1;b) Estimate(x1;b) ∈ i:ℤ fp-> V)
        ∧ (Knowledge(y2;b) Knowledge(x2;b) ∈ b:Id fp-> ℤ × (ℤ × Top)))))
  ∧ (consensus-rel-knowledge-inning-step(V;A;W;x1;x2;y1;y2;a)
    ∨ consensus-rel-knowledge-archive-step(V;A;W;x1;x2;y1;y2;a)
    ∨ consensus-rel-add-knowledge-step(V;A;W;x1;x2;y1;y2;a))

Lemma: consensus-rel-knowledge-step_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[x1,y1:ConsensusState]. ∀[x2,y2:Knowledge(ConsensusState)].
[a:{a:Id| (a ∈ A)} ].
  (consensus-rel-knowledge-step(V;A;W;x1;x2;y1;y2;a) ∈ ℙ)

Definition: consensus-rel-knowledge
consensus-rel-knowledge(V;A;W;x;y) ==
  ∃a:{a:Id| (a ∈ A)} consensus-rel-knowledge-step(V;A;W;fst(x);snd(x);fst(y);snd(y);a)

Lemma: consensus-rel-knowledge_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[x,y:ConsensusState × Knowledge(ConsensusState)].
  (consensus-rel-knowledge(V;A;W;x;y) ∈ ℙ)

Definition: consensus-ts5
consensus-ts5(V;A;W) ==
  <ConsensusState × Knowledge(ConsensusState)
  , <λa.<0, ⊗>, λa.mk_fpf(A;λb.<0, ff>)>
  , λx,y. consensus-rel-knowledge(V;A;W;x;y)
  , λx.∃v:V
        ∀a:{a:Id| (a ∈ A)} 
          ((Inning(fst(x);a) 0 ∈ ℤ)
          ∧ (Estimate(fst(x);a) v ∈ i:ℤ fp-> V)
          ∧ (Knowledge(snd(x);a) mk_fpf(A;λb.<0, ff>) ∈ b:Id fp-> ℤ × (ℤ × Top)))>

Lemma: consensus-ts5_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List].  (consensus-ts5(V;A;W) ∈ transition-system{i:l})

Lemma: consensus-ts5-true-knowledge
[V:Type]
  ∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀x:ts-reachable(consensus-ts5(V;A;W)).
    let x1,x2 
    in ∀a,b:{a:Id| (a ∈ A)} .
         let I,z Knowledge(x2;a)(b) 
         in (I ≤ Inning(x1;b))
            ∧ case z
               of inl(p) =>
               let k,v 
               in k < I
                  ∧ (↑k ∈ dom(Estimate(x1;b)))
                  ∧ (Estimate(x1;b)(k) v ∈ V)
                  ∧ (∀i:ℤ. ¬↑i ∈ dom(Estimate(x1;b)) supposing k < i ∧ i < I)
               inr(p) =>
               ∀i:ℤ. ¬↑i ∈ dom(Estimate(x1;b)) supposing i < 
         supposing ↑b ∈ dom(Knowledge(x2;a))

Lemma: consensus-ts5-archive-invariant
[V:Type]
  ((∀v1,v2:V.  Dec(v1 v2 ∈ V))
   (∃v,v':V. (v v' ∈ V)))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀x:ts-reachable(consensus-ts5(V;A;W)). ∀v:V. ∀b:{a:Id| (a ∈ A)} . ∀i:ℤ.
        (state fst(x) may consider in inning i) supposing 
           ((Estimate(fst(x);b)(i) v ∈ V) and 
           (↑i ∈ dom(Estimate(fst(x);b))))))

Lemma: cs-possible-state-reachable
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[v:V].
  (∀[L:{a:Id| (a ∈ A)}  List]
     (<λa.<0, if a ∈b then else ⊗ fi >, λa.mk_fpf(A;λb.<0, ff>)>
      ∈ ts-reachable(consensus-ts5(V;A;W)))) supposing 
     (two-intersection(A;W) and 
     1 < ||W||)

Lemma: consensus-refinement4
[V:Type]
  ((∀v1,v2:V.  Dec(v1 v2 ∈ V))
   (∃v,v':V. (v v' ∈ V)))
   (∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
        ((1 < ||W|| ∧ two-intersection(A;W))  ts-refinement(consensus-ts4(V;A;W);consensus-ts5(V;A;W);λs.(fst(s))))))

Definition: consensus-event
consensus-event(V;A) ==  Unit ({b:Id| (b ∈ A)}  × i:ℕ × (ℕi × V?))

Lemma: consensus-event_wf
[V:Type]. ∀[A:Id List].  (consensus-event(V;A) ∈ Type)

Definition: inning-event
NextInning ==  inl ⋅

Lemma: inning-event_wf
[V:Type]. ∀[A:Id List].  (NextInning ∈ consensus-event(V;A))

Definition: is-inning-event
is-inning-event(x) ==  isl(x)

Lemma: is-inning-event_wf
[V:Type]. ∀[A:Id List]. ∀[x:consensus-event(V;A)].  (is-inning-event(x) ∈ 𝔹)

Definition: archive-event
Archive(v) ==  inr (inl v) 

Lemma: archive-event_wf
[V:Type]. ∀[A:Id List]. ∀[v:V].  (Archive(v) ∈ consensus-event(V;A))

Definition: consensus-message
consensus-message(b;i;z) ==  inr inr <b, i, z>  

Lemma: consensus-message_wf
[V:Type]. ∀[A:Id List]. ∀[b:{a:Id| (a ∈ A)} ]. ∀[i:ℕ]. ∀[z:ℕi × V?].  (consensus-message(b;i;z) ∈ consensus-event(V;A))

Definition: is-consensus-message
is-consensus-message(e) ==  case of inl(x) => ff inr(x) => case of inl(y) => ff inr(z) => tt

Lemma: is-consensus-message_wf
[V:Type]. ∀[A:Id List]. ∀[e:consensus-event(V;A)].  (is-consensus-message(e) ∈ 𝔹)

Lemma: consensus-event-cases
[V:Type]
  ∀A:Id List. ∀e:consensus-event(V;A).
    ((e NextInning ∈ consensus-event(V;A))
    ∨ (∃v:V. (e Archive(v) ∈ consensus-event(V;A)))
    ∨ (∃b:{a:Id| (a ∈ A)} . ∃i:ℕ. ∃z:ℕi × V?. (e consensus-message(b;i;z) ∈ consensus-event(V;A))))

Definition: consensus-accum
consensus-accum(s;e) ==
  let i,est,knw in 
  case e
   of inl(x) =>
   <1, est, knw>
   inr(x) =>
   case of inl(v) => <i, est ⊕ v, knw> inr(k) => let b,i',z in <i, est, : <i', z> ⊕ knw>

Lemma: consensus-accum_wf
[V:Type]. ∀[A:Id List]. ∀[s:ℤ × j:ℤ fp-> V × b:Id fp-> ℤ × (ℤ × Top)]. ∀[e:consensus-event(V;A)].
  (consensus-accum(s;e) ∈ ℤ × j:ℤ fp-> V × b:Id fp-> ℤ × (ℤ × Top))

Definition: consensus-accum-state
consensus-accum-state(A;L) ==
  accumulate (with value and list item e):
   consensus-accum(s;e)
  over list:
    L
  with starting value:
   <0, ⊗mk_fpf(A;λb.<0, ff>)>)

Lemma: consensus-accum-state_wf
[V:Type]. ∀[A:Id List]. ∀[L:consensus-event(V;A) List].
  (consensus-accum-state(A;L) ∈ ℤ × j:ℤ fp-> V × b:Id fp-> ℤ × (ℤ × Top))

Definition: consensus-state6
consensus-state6(V;A) ==  {a:Id| (a ∈ A)}  ⟶ (consensus-event(V;A) List)

Lemma: consensus-state6_wf
[V:Type]. ∀[A:Id List].  (consensus-state6(V;A) ∈ 𝕌{[1 0]})

Definition: cs-events-to-state
cs-events-to-state(A; s) ==  <λa.let i,est,knw consensus-accum-state(A;s a) in <i, est>, λa.let i,est,knw consensus-\000Caccum-state(A;s a) in knw>

Lemma: cs-events-to-state_wf
[V:Type]. ∀[A:Id List]. ∀[s:consensus-state6(V;A)].
  (cs-events-to-state(A; s) ∈ ConsensusState × Knowledge(ConsensusState))

Definition: one-consensus-event
after e@a ==
  (∀b:{a:Id| (a ∈ A)} ((¬(b a ∈ Id))  ((y b) (x b) ∈ (consensus-event(V;A) List))))
  ∧ ((y a) ((x a) [e]) ∈ (consensus-event(V;A) List))

Lemma: one-consensus-event_wf
[V:Type]. ∀[A:Id List]. ∀[a:{a:Id| (a ∈ A)} ]. ∀[e:consensus-event(V;A)]. ∀[x,y:consensus-state6(V;A)].
  (y after e@a ∈ ℙ)

Definition: consensus-event-constraint
e@a allowed in state ==
  (∀v:V
     ((e Archive(v) ∈ consensus-event(V;A))
      let i,est,knw consensus-accum-state(A;x a) in 
        (i ∈ fpf-domain(est))) ∧ may consider in inning based on knowledge (knw)))
  ∧ (∀b:{a:Id| (a ∈ A)} . ∀i:ℕ. ∀z:ℕi × V?.
       ((e consensus-message(b;i;z) ∈ consensus-event(V;A))
        let i',est,knw consensus-accum-state(A;x b) in 
          (i ≤ i')
          ∧ case z
             of inl(p) =>
             let j,v 
             in (↑j ∈ dom(est)) ∧ (∀k:ℤ(j <  k <  (¬↑k ∈ dom(est)))) ∧ (v est(j) ∈ V)
             inr(a) =>
             ∀j:ℤ(j <  (¬↑j ∈ dom(est)))))

Lemma: consensus-event-constraint_wf
[V:Type]. ∀[A:Id List]. ∀[a:{a:Id| (a ∈ A)} ]. ∀[W:{a:Id| (a ∈ A)}  List List]. ∀[e:consensus-event(V;A)].
[x:consensus-state6(V;A)].
  (e@a allowed in state x ∈ ℙ)

Definition: consensus-ts6
consensus-ts6(V;A;W) ==
  <consensus-state6(V;A)
  , λa.[]
  , λx,y. ∃a:{a:Id| (a ∈ A)} . ∃e:consensus-event(V;A). (e@a allowed in state x ∧ after e@a)
  , λx.∃v:V. ∀a:{a:Id| (a ∈ A)} ((x a) [Archive(v)] ∈ (consensus-event(V;A) List))>

Lemma: consensus-ts6_wf
[V:Type]. ∀[A:Id List]. ∀[W:{a:Id| (a ∈ A)}  List List].  (consensus-ts6(V;A;W) ∈ transition-system{i:l})

Lemma: consensus-refinement5
[V:Type]
  ∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List.
    ((1 < ||W|| ∧ two-intersection(A;W))
     ts-refinement(consensus-ts5(V;A;W);consensus-ts6(V;A;W);λs.cs-events-to-state(A; s)))

Lemma: consensus-ts6-reachability1
[V:Type]
  ∀A:Id List. ∀W:{a:Id| (a ∈ A)}  List List. ∀L:consensus-event(V;A) List.
  ∀x,y:{a:Id| (a ∈ A)}  ⟶ (consensus-event(V;A) List). ∀a:{a:Id| (a ∈ A)} .
    ((∀b:{a:Id| (a ∈ A)} . ∀i:ℕ. ∀z:ℕi × V?.
        ((consensus-message(b;i;z) ∈ L)
         let i',est,knw consensus-accum-state(A;x b) in 
           (i ≤ i')
           ∧ case z
              of inl(p) =>
              let j,v 
              in (↑j ∈ dom(est)) ∧ (∀k:ℤ(¬↑k ∈ dom(est)) supposing (k < and j < k)) ∧ (v est(j) ∈ V)
              inr(a) =>
              ∀j:ℤ. ¬↑j ∈ dom(est) supposing j < i))
        (∀v:V. ∀j:ℕ||L||.
             let i,est,knw consensus-accum-state(A;(x a) firstn(j;L)) in 
             (i ∈ fpf-domain(est))) ∧ may consider in inning based on knowledge (knw) 
             supposing L[j] Archive(v) ∈ consensus-event(V;A))
        (x (ts-rel(consensus-ts6(V;A;W))^*) y)) supposing 
       (((y a) ((x a) L) ∈ (consensus-event(V;A) List)) and 
       (∀b:{a:Id| (a ∈ A)} (y b) (x b) ∈ (consensus-event(V;A) List) supposing ¬(b a ∈ Id)))

Definition: consensus-rcv
consensus-rcv(V;A) ==  ({b:Id| (b ∈ A)}  × ℕ × V)

Lemma: consensus-rcv_wf
[V:Type]. ∀[A:Id List].  (consensus-rcv(V;A) ∈ Type)

Lemma: decidable__equal_consensus-rcv
[V:Type]. ((∀v,w:V.  Dec(v w ∈ V))  (∀A:Id List. ∀x,y:consensus-rcv(V;A).  Dec(x y ∈ consensus-rcv(V;A))))

Definition: cs-initial-rcv
Init[v] ==  inl v

Lemma: cs-initial-rcv_wf
[V:Type]. ∀[A:Id List]. ∀[v:V].  (Init[v] ∈ consensus-rcv(V;A))

Definition: cs-rcv-vote
Vote[a;i;v] ==  inr <a, i, v> 

Lemma: cs-rcv-vote_wf
[V:Type]. ∀[A:Id List]. ∀[a:{a:Id| (a ∈ A)} ]. ∀[i:ℕ]. ∀[v:V].  (Vote[a;i;v] ∈ consensus-rcv(V;A))

Definition: rcv-vote?
rcv-vote?(x) ==  case of inl(z) => ff inr(z) => tt

Lemma: rcv-vote?_wf
[V:Type]. ∀[A:Id List]. ∀[x:consensus-rcv(V;A)].  (rcv-vote?(x) ∈ 𝔹)

Definition: rcvd-vote
rcvd-vote(x) ==  outr(x)

Lemma: rcvd-vote_wf
[V:Type]. ∀[A:Id List]. ∀[x:consensus-rcv(V;A)].  rcvd-vote(x) ∈ {b:Id| (b ∈ A)}  × ℕ × supposing ↑rcv-vote?(x)

Definition: rcvd-inning-gt
i <inning(r) ==  rcv-vote?(r) ∧b let a,j,v rcvd-vote(r) in i <j

Lemma: rcvd-inning-gt_wf
[V:Type]. ∀[A:Id List]. ∀[r:consensus-rcv(V;A)]. ∀[i:ℤ].  (i <inning(r) ∈ 𝔹)

Lemma: assert-rcvd-inning-gt
[V:Type]
  ∀A:Id List. ∀r:consensus-rcv(V;A). ∀i:ℤ.
    (↑i <inning(r) ⇐⇒ ∃a:{b:Id| (b ∈ A)} . ∃v:V. ∃j:ℕ(i < j ∧ (r Vote[a;j;v] ∈ consensus-rcv(V;A))))

Definition: rcvd-inning-eq
inning(r) =z ==  rcv-vote?(r) ∧b let a,j,v rcvd-vote(r) in (i =z j)

Lemma: rcvd-inning-eq_wf
[V:Type]. ∀[A:Id List]. ∀[r:consensus-rcv(V;A)]. ∀[i:ℤ].  (inning(r) =z i ∈ 𝔹)

Lemma: assert-rcvd-inning-eq
[V:Type]
  ∀A:Id List. ∀r:consensus-rcv(V;A). ∀i:ℕ.
    (↑inning(r) =z ⇐⇒ ∃a:{b:Id| (b ∈ A)} . ∃v:V. (r Vote[a;i;v] ∈ consensus-rcv(V;A)))

Definition: votes-from-inning
votes-from-inning(i;L) ==  mapfilter(λr.let a,j,v rcvd-vote(r) in <a, v>r.inning(r) =z i;L)

Lemma: votes-from-inning_wf
[V:Type]. ∀[A:Id List]. ∀[L:consensus-rcv(V;A) List]. ∀[i:ℤ].  (votes-from-inning(i;L) ∈ ({b:Id| (b ∈ A)}  × V) List)

Lemma: member-votes-from-inning
[V:Type]
  ∀A:Id List. ∀L:consensus-rcv(V;A) List. ∀i:ℕ. ∀b:{b:Id| (b ∈ A)} . ∀v:V.
    ((<b, v> ∈ votes-from-inning(i;L)) ⇐⇒ (Vote[b;i;v] ∈ L))

Lemma: votes-from-inning-is-nil
[V:Type]. ∀[A:Id List]. ∀[L:consensus-rcv(V;A) List]. ∀[i,n:ℤ].
  (votes-from-inning(i;L) []) supposing (n < and (filter(λr.n <inning(r);L) [] ∈ (consensus-rcv(V;A) List)))

Lemma: rcvd-innings-nil
[V:Type]. ∀[A:Id List]. ∀[L:consensus-rcv(V;A) List]. ∀[i,n:ℤ].
  (filter(λr.i <inning(r);L) []) supposing 
     ((n ≤ i) and 
     (filter(λr.n <inning(r);L) [] ∈ (consensus-rcv(V;A) List)))

Definition: archive-condition
archive-condition(V;A;t;f;n;v;L) ==
  ∃L':consensus-rcv(V;A) List
   ∃r:consensus-rcv(V;A)
    ((L (L' [r]) ∈ (consensus-rcv(V;A) List))
    ∧ (((L' [] ∈ (consensus-rcv(V;A) List))
      ∧ (((r Init[v] ∈ consensus-rcv(V;A)) ∧ (n 0 ∈ ℤ))
        ∨ ((0 ≤ n) ∧ (∃a:{a:Id| (a ∈ A)} (r Vote[a;n;v] ∈ consensus-rcv(V;A))))))
      ∨ ((0 < n
        ∧ (||values-for-distinct(IdDeq;votes-from-inning(n 1;L'))|| ≤ (2 t))
        ∧ (↑null(filter(λr.n 1 <inning(r);L'))))
        ∧ ((∃a:{a:Id| (a ∈ A)} (r Vote[a;n;v] ∈ consensus-rcv(V;A)))
          ∨ ((((2 t) 1) ≤ ||values-for-distinct(IdDeq;votes-from-inning(n 1;L))||)
            ∧ ((f values-for-distinct(IdDeq;votes-from-inning(n 1;L))) v ∈ V))))))

Lemma: archive-condition_wf
[V:Type]. ∀[A:Id List]. ∀[t:ℕ]. ∀[f:(V List) ⟶ V]. ∀[L:consensus-rcv(V;A) List]. ∀[n:ℤ]. ∀[v:V].
  (archive-condition(V;A;t;f;n;v;L) ∈ ℙ)

Lemma: archive-condition-append-init
[V:Type]
  ∀A:Id List. ∀t:ℕ. ∀f:(V List) ⟶ V. ∀L:consensus-rcv(V;A) List. ∀n:ℤ. ∀v,v2:V.
    (archive-condition(V;A;t;f;n;v;L [Init[v2]])
    ⇐⇒ {(L [] ∈ (consensus-rcv(V;A) List)) ∧ (n 0 ∈ ℤ) ∧ (v2 v ∈ V)})

Lemma: archive-condition-append-vote
[V:Type]
  ∀A:Id List. ∀t:ℕ. ∀f:(V List) ⟶ V. ∀L:consensus-rcv(V;A) List. ∀n:ℤ. ∀v,v2:V. ∀a:{b:Id| (b ∈ A)} . ∀i:ℕ.
    (archive-condition(V;A;t;f;n;v;L [Vote[a;i;v2]])
    ⇐⇒ ((L [] ∈ (consensus-rcv(V;A) List)) ∧ (i n ∈ ℤ) ∧ (v v2 ∈ V))
        ∨ ((0 < n ∧ (||values-for-distinct(IdDeq;votes-from-inning(n 1;L))|| ≤ (2 t)))
          ∧ (↑null(filter(λr.n 1 <inning(r);L)))
          ∧ (((i n ∈ ℤ) ∧ (v v2 ∈ V))
            ∨ ((((2 t) 1) ≤ ||values-for-distinct(IdDeq;votes-from-inning(n 1;L [Vote[a;i;v2]]))||)
              ∧ ((f values-for-distinct(IdDeq;votes-from-inning(n 1;L [Vote[a;i;v2]]))) v ∈ V)))))

Lemma: archive-condition-nil
[V:Type]. ∀A:Id List. ∀t:ℕ. ∀f:(V List) ⟶ V. ∀n:ℤ. ∀v:V.  (archive-condition(V;A;t;f;n;v;[]) ⇐⇒ False)

Definition: consensus-accum-num
consensus-accum-num(num;f;s;r) ==
  let b,n,as,vs,w in case r
   of inl(v) =>
   if (n =z 0) then <tt, 1, [], [], v> else <ff, n, as, vs, w> fi 
   inr(z) =>
   let a,i,v in 
   if i <then <ff, n, as, vs, w>
   if 1 <then <tt, 1, [a], [v], v>
   else let as' as [a] in
         let vs' vs [v] in
         if (||remove-repeats(IdDeq;as')|| =z num)
         then <tt, 1, [], [], values-for-distinct(IdDeq;zip(as';vs'))>
         else <ff, n, as', vs', w>
         fi 
   fi 

Lemma: consensus-accum-num_wf
[V:Type]. ∀[A:Id List]. ∀[num:ℤ]. ∀[f:(V List) ⟶ V]. ∀[s:𝔹 × ℤ × {a:Id| (a ∈ A)}  List × List × V].
[r:consensus-rcv(V;A)].
  (consensus-accum-num(num;f;s;r) ∈ 𝔹 × ℤ × {a:Id| (a ∈ A)}  List × List × V)

Definition: int_consensus_accum
int_consensus_accum(num) ==  λs,r. consensus-accum-num(num;λL.strict-majority-or-max(L);s;r)

Lemma: int_consensus_accum_wf
[n:ℤ]
  (int_consensus_accum(n) ∈ (𝔹 × ℤ × Id List × ℤ List × ℤ) ⟶ (ℤ (Id × ℤ × ℤ)) ⟶ (𝔹 × ℤ × Id List × ℤ List × ℤ))

Definition: int_consensus_init
int_consensus_init() ==  <ff, 0, [], [], 0>

Lemma: int_consensus_init_wf
[T1,T:Type].  (int_consensus_init() ∈ 𝔹 × ℤ × List × T1 List × ℤ)

Definition: int_consensus_test
int_consensus_test(s) ==  let b,i,as,vs,w in if then inl <1, w> else inr 0  fi 

Lemma: int_consensus_test_wf
[s:𝔹 × ℤ × Id List × ℤ List × ℤ]. (int_consensus_test(s) ∈ ℤ × ℤ Top)

Definition: consensus-accum-num-state
consensus-accum-num-state(t;f;v0;L) ==
  accumulate (with value and list item r):
   consensus-accum-num((2 t) 1;f;s;r)
  over list:
    L
  with starting value:
   <ff, 0, [], [], v0>)

Lemma: consensus-accum-num-state_wf
[V:Type]. ∀[A:Id List]. ∀[t:ℕ]. ∀[f:(V List) ⟶ V]. ∀[v0:V]. ∀[L:consensus-rcv(V;A) List].
  (consensus-accum-num-state(t;f;v0;L) ∈ 𝔹 × ℤ × {a:Id| (a ∈ A)}  List × List × V)

Lemma: consensus-rcv-crosses-threshold
[V:Type]
  ∀A:Id List. ∀t:ℕ+. ∀n:ℤ. ∀L:consensus-rcv(V;A) List. ∀r:consensus-rcv(V;A).
    (∃a:{a:Id| (a ∈ A)} 
      ∃v:V. ((r Vote[a;n;v] ∈ consensus-rcv(V;A)) ∧ (¬↑null(filter(λr.n 1 <inning(r);L))) ∧ (0 ≤ n))) supposing 
       ((((2 t) 1) ≤ ||values-for-distinct(IdDeq;votes-from-inning(n;L [r]))||) and 
       (||values-for-distinct(IdDeq;votes-from-inning(n;L))|| ≤ (2 t)))

Lemma: consensus-rcv-crosses-size
[V:Type]. ∀[A:Id List]. ∀[t:ℕ+]. ∀[n:ℤ]. ∀[L:consensus-rcv(V;A) List]. ∀[r:consensus-rcv(V;A)].
  (||remove-repeats(IdDeq;map(λp.(fst(p));votes-from-inning(n;L [r])))|| ((2 t) 1) ∈ ℤsupposing 
     ((((2 t) 1) ≤ ||values-for-distinct(IdDeq;votes-from-inning(n;L [r]))||) and 
     (||values-for-distinct(IdDeq;votes-from-inning(n;L))|| ≤ (2 t)))

Lemma: vote-crosses-threshold
[V:Type]. ∀[A:Id List]. ∀[t:ℕ+]. ∀[n1:ℕ]. ∀[n2:ℤ]. ∀[v1:V]. ∀[L1:consensus-rcv(V;A) List]. ∀[a:{a:Id| (a ∈ A)} ].
  ({(n1 n2 ∈ ℤ) ∧ (¬↑null(filter(λr.n1 1 <inning(r);L1)))}) supposing 
     ((((2 t) 1) ≤ ||values-for-distinct(IdDeq;votes-from-inning(n2;L1 [Vote[a;n1;v1]]))||) and 
     (||values-for-distinct(IdDeq;votes-from-inning(n2;L1))|| ≤ (2 t)))

Lemma: archive-condition-one-one
[V:Type]. ∀[A:Id List]. ∀[t:ℕ+]. ∀[f:(V List) ⟶ V]. ∀[L:consensus-rcv(V;A) List]. ∀[n1,n2:ℤ]. ∀[v1,v2:V].
  ({(n1 n2 ∈ ℤ) ∧ (v1 v2 ∈ V)}) supposing 
     (archive-condition(V;A;t;f;n2;v2;L) and 
     archive-condition(V;A;t;f;n1;v1;L))

Lemma: archive-condition-innings
[V:Type]. ∀[A:Id List]. ∀[t:ℕ+]. ∀[f:(V List) ⟶ V]. ∀[L1,L2:consensus-rcv(V;A) List]. ∀[n1,n2:ℤ]. ∀[v1,v2:V].
  (n1 < n2) supposing (archive-condition(V;A;t;f;n2;v2;L2) and L1 < L2 and archive-condition(V;A;t;f;n1;v1;L1))

Lemma: archive-condition-single
[V:Type]. ∀[A:Id List]. ∀[t:ℕ+]. ∀[f:(V List) ⟶ V]. ∀[L:consensus-rcv(V;A) List]. ∀[n:ℤ]. ∀[v:V].
  ∀[L1:consensus-rcv(V;A) List]. ∀[v1:V]. archive-condition(V;A;t;f;n;v1;L1)) supposing L1 < 
  supposing archive-condition(V;A;t;f;n;v;L)

Lemma: consensus-accum-num-property1
[V:Type]
  ∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V. ∀v0:V. ∀L:consensus-rcv(V;A) List.
    let b,i,as,vs,v consensus-accum-num-state(t;f;v0;L) in (filter(λr.i 1 <inning(r);L)
                                                             []
                                                             ∈ (consensus-rcv(V;A) List))
    ∧ (||as|| ||vs|| ∈ ℤ)
    ∧ (zip(as;vs) votes-from-inning(i 1;L) ∈ (({b:Id| (b ∈ A)}  × V) List))
    ∧ (0 ≤ i)
    ∧ 1 ≤ supposing ¬↑null(L)
    ∧ (||values-for-distinct(IdDeq;votes-from-inning(i 1;L))|| ≤ (2 t))

Lemma: consensus-accum-num-property2
[V:Type]
  ∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V. ∀v0:V. ∀L:consensus-rcv(V;A) List.
    let b,i,as,vs,v consensus-accum-num-state(t;f;v0;L) in
     (((2 t) 1) ≤ ||remove-repeats(IdDeq;map(λp.(fst(p));votes-from-inning(i 2;L)))||) supposing 
        ((votes-from-inning(i 1;L) [] ∈ (({b:Id| (b ∈ A)}  × V) List)) and 
        1 < i)

Lemma: consensus-accum-num-archives
[V:Type]
  ∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V. ∀v0:V. ∀L:consensus-rcv(V;A) List.
    let b,i,as,vs,v consensus-accum-num-state(t;f;v0;L) in archive-condition(V;A;t;f;i 1;v;L) supposing ↑b

Lemma: archive-consensus-accum-num
[V:Type]. ∀[A:Id List]. ∀[t:ℕ+]. ∀[f:(V List) ⟶ V]. ∀[v0:V]. ∀[L:consensus-rcv(V;A) List]. ∀[v:V]. ∀[i:ℤ].
  ↑(fst(consensus-accum-num-state(t;f;v0;L))) supposing archive-condition(V;A;t;f;i;v;L)

Lemma: consensus-accum-num-property3
[V:Type]
  ∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V. ∀v0:V. ∀L:consensus-rcv(V;A) List.
    let b,i,as,vs,v consensus-accum-num-state(t;f;v0;L) in if b
    then archive-condition(V;A;t;f;i 1;v;L)
    else ∀v:V. archive-condition(V;A;t;f;i;v;L))
    fi 

Lemma: archive-condition-threshold-accum
[V:Type]
  ∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V. ∀v0:V. ∀L:consensus-rcv(V;A) List. ∀n:ℕ. ∀v:V.
    (archive-condition(V;A;t;f;n;v;L)
    ⇐⇒ let b,i,as,vs,w accumulate (with value and list item r):
                           consensus-accum-num((2 t) 1;f;s;r)
                          over list:
                            L
                          with starting value:
                           <ff, 0, [], [], v0>in (↑b) ∧ ((n 1) i ∈ ℤ) ∧ (v w ∈ V))

Lemma: decidable__archive-condition
[V:Type]
  (V
   (∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V. ∀L:consensus-rcv(V;A) List.
        Dec(∃n:ℕ. ∃v:V. archive-condition(V;A;t;f;n;v;L))))

Definition: three-consensus-ts
three-consensus-ts(V;A;t;f) ==
  <{a:Id| (a ∈ A)}  ⟶ (consensus-rcv(V;A) List)
  , λa.[]
  , λx,y. ∃a:{a:Id| (a ∈ A)} 
           ∃e:consensus-rcv(V;A)
            ((∀b:{a:Id| (a ∈ A)} . ∀i:ℕ. ∀v:V.
                ((e Vote[b;i;v] ∈ consensus-rcv(V;A))
                 ((∃L:consensus-rcv(V;A) List. (L ≤ b ∧ archive-condition(V;A;t;f;i;v;L))) ∧ (e ∈ a)))))
            ∧ (∀b:{a:Id| (a ∈ A)} ((¬(b a ∈ Id))  ((y b) (x b) ∈ (consensus-rcv(V;A) List))))
            ∧ ((y a) ((x a) [e]) ∈ (consensus-rcv(V;A) List)))
  , λx.∃v:V. ∀a:{a:Id| (a ∈ A)} ((x a) [Init[v]] ∈ (consensus-rcv(V;A) List))>

Lemma: three-consensus-ts_wf
[V:Type]. ∀[A:Id List]. ∀[t:ℕ]. ∀[f:(V List) ⟶ V].  (three-consensus-ts(V;A;t;f) ∈ transition-system{i:l})

Definition: three-cs-decided
three-cs-decided(V;A;t;f;s;v) ==
  ∃i:ℤ
   ∃ws:{a:Id| (a ∈ A)}  List
    (no_repeats({a:Id| (a ∈ A)} ;ws)
    ∧ (||ws|| ((2 t) 1) ∈ ℤ)
    ∧ (∀a∈ws.∃L:consensus-rcv(V;A) List. (L ≤ a ∧ archive-condition(V;A;t;f;i;v;L))))

Lemma: three-cs-decided_wf
[V:Type]. ∀[A:Id List]. ∀[t:ℕ+]. ∀[f:(V List) ⟶ V]. ∀[v:V]. ∀[s:{a:Id| (a ∈ A)}  ⟶ (consensus-rcv(V;A) List)].
  (three-cs-decided(V;A;t;f;s;v) ∈ ℙ)

Lemma: three-cs-vote-invariant
V:Type. ∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V. ∀s:ts-type(three-consensus-ts(V;A;t;f)).
  ((ts-init(three-consensus-ts(V;A;t;f)) (ts-rel(three-consensus-ts(V;A;t;f))^*) s)
   (∀a:{a:Id| (a ∈ A)} . ∀n:ℕ. ∀b:{a:Id| (a ∈ A)} . ∀v1:V.
        ((Vote[b;n;v1] ∈ a)  (∃L:consensus-rcv(V;A) List. (L ≤ b ∧ archive-condition(V;A;t;f;n;v1;L))))))

Lemma: three-cs-archive-condition
V:Type. ∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V. ∀s:ts-type(three-consensus-ts(V;A;t;f)).
  ((ts-init(three-consensus-ts(V;A;t;f)) (ts-rel(three-consensus-ts(V;A;t;f))^*) s)
   (∀v:V. ∀a:{a:Id| (a ∈ A)} . ∀n:ℕ+. ∀L:consensus-rcv(V;A) List.
        (L ≤ a
         archive-condition(V;A;t;f;n;v;L)
         (∃as:{a:Id| (a ∈ A)}  List
             (no_repeats({a:Id| (a ∈ A)} ;as)
             ∧ (||as|| ((2 t) 1) ∈ ℤ)
             ∧ (∃vs:V List
                 ((||vs|| ||as|| ∈ ℤ)
                 ∧ (v (f vs) ∈ V)
                 ∧ (∀i:ℕ||as||
                      ∃L:consensus-rcv(V;A) List. (L ≤ as[i] ∧ archive-condition(V;A;t;f;n 1;vs[i];L))))))))))

Lemma: three-cs-archive-invariant
[V:Type]
  ∀eq:EqDecider(V). ∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V.
    ((∀vs:V List. (f vs ∈ vs) supposing ||vs|| ≥ )
     (∀s:ts-reachable(three-consensus-ts(V;A;t;f)). ∀v:V. ∀a:{a:Id| (a ∈ A)} . ∀n:ℤ. ∀L:consensus-rcv(V;A) List.
          (L ≤ a
           archive-condition(V;A;t;f;n;v;L)
           (∃a∈A. (||s a|| ≥ ) ∧ (hd(s a) Init[v] ∈ consensus-rcv(V;A))))))

Lemma: three-cs-no-repeated-votes
V:Type. ∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V. ∀s:ts-reachable(three-consensus-ts(V;A;t;f)). ∀a:{a:Id| (a ∈ A)} .
  no_repeats(consensus-rcv(V;A);filter(λx.rcv-vote?(x);s a))

Lemma: three-cs-safety1
[V:Type]. ∀[eq:EqDecider(V)]. ∀[A:Id List]. ∀[t:ℕ+].
  (∀[f:(V List) ⟶ V]
     ∀[v,w:V]. ∀[s,s':ts-reachable(three-consensus-ts(V;A;t;f))].
       (v w ∈ V) supposing 
          (three-cs-decided(V;A;t;f;s';w) and 
          three-cs-decided(V;A;t;f;s;v) and 
          (s (ts-rel(three-consensus-ts(V;A;t;f))^*) s')) 
     supposing ∀vs:V List. ∀v:V.
                 ((||vs|| ((2 t) 1) ∈ ℤ)
                  ((t 1) ≤ ||filter(λx.(eqof(eq) v);vs)||)
                  ((f vs) v ∈ V))) supposing 
     ((||A|| ((3 t) 1) ∈ ℤand 
     no_repeats(Id;A))

Lemma: three-cs-safety2
[V:Type]
  ∀eq:EqDecider(V). ∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V.
    ((∀vs:V List. (f vs ∈ vs) supposing ||vs|| ≥ )
     (∀v:V. ∀s:ts-reachable(three-consensus-ts(V;A;t;f)).
          (three-cs-decided(V;A;t;f;s;v)  (∃a∈A. (||s a|| ≥ ) ∧ (hd(s a) Init[v] ∈ consensus-rcv(V;A))))))

Lemma: three-cs-safety
[V:Type]
  ∀eq:EqDecider(V). ∀A:Id List. ∀t:ℕ+. ∀f:(V List) ⟶ V.
    ((∀vs:V List. (f vs ∈ vs) supposing ||vs|| ≥ )
        (∀v:V. ∀s:ts-reachable(three-consensus-ts(V;A;t;f)).
             (three-cs-decided(V;A;t;f;s;v)
              ((∃a∈A. (||s a|| ≥ ) ∧ (hd(s a) Init[v] ∈ consensus-rcv(V;A)))
                ∧ (∀w:V. ∀s':ts-reachable(three-consensus-ts(V;A;t;f)).
                     ((s (ts-rel(three-consensus-ts(V;A;t;f))^*) s')
                      three-cs-decided(V;A;t;f;s';w)
                      (v w ∈ V))))))) supposing 
       ((∀vs:V List. ∀v:V.
           ((f vs) v ∈ V) supposing (((t 1) ≤ ||filter(λx.(eqof(eq) v);vs)||) and (||vs|| ((2 t) 1) ∈ ℤ))) a\000Cnd 
       (||A|| ((3 t) 1) ∈ ℤand 
       no_repeats(Id;A))

Lemma: three-cs-int-safety
A:Id List. ∀t:ℕ+.
  (∀v:ℤ. ∀s:ts-reachable(three-consensus-ts(ℤ;A;t;λL.strict-majority-or-max(L))).
     (three-cs-decided(ℤ;A;t;λL.strict-majority-or-max(L);s;v)
      ((∃a∈A. (||s a|| ≥ ) ∧ (hd(s a) Init[v] ∈ consensus-rcv(ℤ;A)))
        ∧ (∀w:ℤ. ∀s':ts-reachable(three-consensus-ts(ℤ;A;t;λL.strict-majority-or-max(L))).
             ((s (ts-rel(three-consensus-ts(ℤ;A;t;λL.strict-majority-or-max(L)))^*) s')
              three-cs-decided(ℤ;A;t;λL.strict-majority-or-max(L);s';w)
              (v w ∈ ℤ)))))) supposing 
     ((||A|| ((3 t) 1) ∈ ℤand 
     no_repeats(Id;A))

Definition: consensus-rcvs-to-consensus-events
consensus-rcvs-to-consensus-events(f;t;v0;L) ==
  accumulate (with value and list item r):
   let X,Y 
   in let b,i,as,vs,v accumulate (with value and list item r):
                         consensus-accum-num((2 t) 1;f;s;r)
                        over list:
                          [r]
                        with starting value:
                         <ff, 0, [], [], v0>in <X
                                                  if rcv-vote?(r)
                                                    then let a,i,v rcvd-vote(r) in 
                                                         [consensus-message(a;i 1;inl <i, v>)]
                                                    else []
                                                    fi 
                                                  if b
                                                    then if null(as)
                                                         then [Archive(v); NextInning]
                                                         else map(λn.NextInning;upto(i 
                                                                  ||filter(λx.is-inning-event(x);X)||))
                                                              [Archive(v); NextInning]
                                                         fi 
                                                    else []
                                                    fi 
                                                 [r]
                                                 >
  over list:
    L
  with starting value:
   <[], []>)

Lemma: consensus-rcvs-to-consensus-events_wf
[V:Type]. ∀[A:Id List]. ∀[t:ℕ+]. ∀[f:(V List) ⟶ V]. ∀[v0:V]. ∀[L:consensus-rcv(V;A) List].
  (consensus-rcvs-to-consensus-events(f;t;v0;L) ∈ consensus-event(V;A) List × (consensus-rcv(V;A) List))

Lemma: pi2-consensus-rcvs-to-consensus-events
[V:Type]. ∀[A:Id List]. ∀[t:ℕ+]. ∀[f:(V List) ⟶ V]. ∀[v0:V]. ∀[L:consensus-rcv(V;A) List].
  ((snd(consensus-rcvs-to-consensus-events(f;t;v0;L))) L ∈ (consensus-rcv(V;A) List))

Definition: three-consensus-ref-map
three-consensus-ref-map(v0;t;f) ==  λs,a. (fst(consensus-rcvs-to-consensus-events(f;t;v0;s a)))

Lemma: three-consensus-ref-map_wf
[V:Type]. ∀[A:Id List]. ∀[t:ℕ+]. ∀[f:(V List) ⟶ V]. ∀[v0:V]. ∀[W:{a:Id| (a ∈ A)}  List List].
  (three-consensus-ref-map(v0;t;f) ∈ ts-type(three-consensus-ts(V;A;t;f)) ⟶ ts-type(consensus-ts6(V;A;W)))

Definition: es-decl-set
DeclSet ==  S:Id List × {i:Id| (i ∈ S)}  ⟶ x:Id fp-> Type × (i:{i:Id| (i ∈ S)}  ⟶ k:{k:Knd| ↑hasloc(k;i)}  fp-> Type)

Lemma: es-decl-set_wf
DeclSet ∈ 𝕌'

Definition: es-decl-set-single
es-decl-set-single(i;ds;da) ==  <[i], λi.ds, λi.da>

Lemma: es-decl-set-single_wf
[i:Id]. ∀[ds:x:Id fp-> Type]. ∀[da:k:{k:Knd| ↑hasloc(k;i)}  fp-> Type].  (es-decl-set-single(i;ds;da) ∈ DeclSet)

Definition: es-decl-set-domain
|dd| ==  fst(dd)

Lemma: es-decl-set-domain_wf
[dd:DeclSet]. (|dd| ∈ Id List)

Definition: es-decl-set-ds
ds(dd;i) ==  (fst(snd(dd))) i

Lemma: es-decl-set-ds_wf
[dd:DeclSet]. ∀[i:Id].  ds(dd;i) ∈ x:Id fp-> Type supposing (i ∈ |dd|)

Definition: es-decl-set-da
da(dd;i) ==  (snd(snd(dd))) i

Lemma: es-decl-set-da_wf
[dd:DeclSet]. ∀[i:Id].  da(dd;i) ∈ k:{k:Knd| ↑hasloc(k;i)}  fp-> Type supposing (i ∈ |dd|)

Definition: es-decl-set-avoids
dd avoids ==  let S,ds,da dd in ∀i:Id. ((i ∈ S)  (¬↑x ∈ dom(ds i)))

Lemma: es-decl-set-avoids_wf
[dd:DeclSet]. ∀[x:Id].  (dd avoids x ∈ ℙ)

Definition: es-decl-set-avoids-tag
es-decl-set-avoids-tag(dd;b) ==
  let S,ds,da dd in 
  ∀i:Id. ((i ∈ S)  (∀k:Knd. ((k ∈ fpf-domain(da i))  (↑isrcv(k))  (tag(k) b ∈ Id)))))

Lemma: es-decl-set-avoids-tag_wf
[dd:DeclSet]. ∀[x:Id].  (es-decl-set-avoids-tag(dd;x) ∈ ℙ)

Definition: es-decl-set-declares-tag
es-decl-set-declares-tag{i:l}(dd;b;T) ==
  let S,ds,da dd in 
  ∀i:Id. ((i ∈ S)  (∀k:Knd. ((k ∈ fpf-domain(da i))  (↑isrcv(k))  (tag(k) b ∈ Id)  (da i(k) T ∈ Type))))

Lemma: es-decl-set-declares-tag_wf
[dd:DeclSet]. ∀[x:Id]. ∀[T:Type].  (es-decl-set-declares-tag{i:l}(dd;x;T) ∈ ℙ')

Definition: es-decl-sets-compatible
dd1 || dd2 ==
  let S1,ds1,da1 dd1 in 
  let S2,ds2,da2 dd2 in 
  ∀i:Id. ((i ∈ S1)  (i ∈ S2)  (da1 || da2 i ∧ ds1 || ds2 i))

Lemma: es-decl-sets-compatible_wf
[dd1,dd2:DeclSet].  (dd1 || dd2 ∈ ℙ')

Definition: es-decl-set-join
es-decl-set-join(dd1;dd2) ==
  let S1,ds1,da1 dd1 in 
  let S2,ds2,da2 dd2 in 
  <remove-repeats(IdDeq;S1 S2)
  , λi.if i ∈b S1
       then if i ∈b S2
            then if null(fpf-domain(da1 i)) then ds2 i
                 if null(fpf-domain(da2 i)) then ds1 i
                 else ds1 i ⊕ ds2 i
                 fi 
            else ds1 i
            fi 
       else ds2 i
       fi 
  , λi.if i ∈b S1 then if i ∈b S2 then da1 i ⊕ da2 else da1 fi  else da2 fi >

Lemma: es-decl-set-join_wf
[dd1,dd2:DeclSet].  (es-decl-set-join(dd1;dd2) ∈ DeclSet)

Lemma: es-decl-set-join-domain
[dd1,dd2:DeclSet].  (|es-decl-set-join(dd1;dd2)| remove-repeats(IdDeq;|dd1| |dd2|))

Definition: es-decl-sets-sub
dd1 ⊆ dd2 ==
  let S1,ds1,da1 dd1 in 
  let S2,ds2,da2 dd2 in 
  ∀i:Id. ((i ∈ S1)  ((i ∈ S2) ∧ da1 i ⊆ da2 i ∧ ds1 i ⊆ ds2 i))

Lemma: es-decl-sets-sub_wf
[dd1,dd2:DeclSet].  (dd1 ⊆ dd2 ∈ ℙ')

Definition: normal-decl-set
normal-decl-set(dd) ==  let S,ds,da dd in ∀i:{i:Id| (i ∈ S)} (Normal(ds i) ∧ Normal(da i))

Lemma: normal-decl-set_wf
[dd:DeclSet]. (normal-decl-set(dd) ∈ ℙ)

Definition: decl-set-read-allowed
decl-set-read-allowed(R;dd) ==
  let S,ds,da dd in 
  ∀i:{i:Id| (i ∈ S)} l_all(fpf-domain(da i); Knd; k.↑read-allowed(R;k;i;fpf-domain(ds i)))

Definition: R-decls-compat
R-decls-compat(R;dd) ==
  case of 
  Rnone => True
  Rplus(left,right)=>rec1,rec2.rec1 ∧ rec2
  Rinit(loc,T,x,v)=> (loc ∈ |dd|)  || ds(dd;loc)
  Rframe(loc,T,x,L)=> (loc ∈ |dd|)  || ds(dd;loc)
  Rsframe(lnk,tag,L)=> True
  Reffect(loc,ds,knd,T,x,f)=> (loc ∈ |dd|)  (x || ds(dd;loc) ∧ ds || ds(dd;loc) ∧ knd || da(dd;loc))
  Rsends(ds,knd,T,l,dt,g)=> ((source(l) ∈ |dd|)  (knd || da(dd;source(l)) ∧ ds || ds(dd;source(l))))
  ∧ ((destination(l) ∈ |dd|)  lnk-decl(l;fpf-restrict(dt;λtg.tg ∈b map(λp.(fst(p));g))) || da(dd;destination(l)))
  Rpre(loc,ds,a,p,P)=> (loc ∈ |dd|)  (locl(a) Outcome || da(dd;loc) ∧ ds || ds(dd;loc))
  Raframe(loc,k,L)=> True
  Rbframe(loc,k,L)=> True
  Rrframe(loc,x,L)=> True

Definition: state-var-allowed
state-var-allowed{i:l}(R;dd;x;T) ==
  let S,ds,da dd in 
  ∀i:{i:Id| (i ∈ S)} 
    (l_all(fpf-domain(da i); Knd; k.(↑read-allowed(R;k;i;[x])) ∧ (↑write-allowed(R;k;i;x)))
    ∧ (¬↑R-affects(R;x;i))
    ∧ R-decls-compat(R;es-decl-set-single(i;x T;⊗)))

Definition: state-var-read-allowed
state-var-read-allowed{i:l}(R;dd;x;T) ==
  let S,ds,da dd in 
  ∀i:{i:Id| (i ∈ S)} 
    (l_all(fpf-domain(da i); Knd; k.↑read-allowed(R;k;i;[x])) ∧ R-decls-compat(R;es-decl-set-single(i;x T;⊗)))

Definition: flow-allowed
flow-allowed{i:l}(R;dd;G;a;b;T) ==
  let S,ds,da dd in 
  ∀i:{i:Id| (i ∈ S)} . ∀j:{j:Id| (i⟶j)∈G} .
    ((¬(<(link(a j) from to j), b> ∈ R-lnktags(R)))
    ∧ l_all(fpf-domain(da i); {k:Knd| ↑hasloc(k;i)} k.↑send-allowed(R;k;(link(a j) from to j);[b]))
    ∧ R-decls-compat(R;es-decl-set-single(j;⊗;rcv((link(a j) from to j),b) T)))

Definition: public-decls
public-decls(R;dd) ==
  let S,ds,da dd in 
  ∀i:{i:Id| (i ∈ S)} 
    (l_all(fpf-domain(da i); Knd; k.(¬↑write-restricted(R;i;k)) ∧ (¬↑send-restricted(R;i;k)))
    ∧ l_all(fpf-domain(ds i); Id; y.¬↑read-restricted(R;i;y)))

Definition: class-program
ClassProgram(T) ==
  i:Id fp-> A:Type
            × ks:{k:Knd| ↑hasloc(k;i)}  List
            × typ:{k:Knd| (k ∈ ks)}  ⟶ Type
            × k:{k:Knd| (k ∈ ks)}  ⟶ (typ k) ⟶ A ⟶ (T Top)
            × A ⟶ k:{k:Knd| (k ∈ ks)}  ⟶ (typ k) ⟶ A
            × A

Lemma: class-program_wf
[T:Type]. (ClassProgram(T) ∈ 𝕌')

Lemma: class-program-monotonic
[T,T':Type].  ClassProgram(T) ⊆ClassProgram(T') supposing T ⊆T'

Definition: cp-domain
cp-domain(cp) ==  fpf-domain(cp)

Lemma: cp-domain_wf
[cp:ClassProgram(Top)]. (cp-domain(cp) ∈ Id List)

Definition: cp-kinds
cp-kinds(cp) ==  λi.let A,ks,typ,h,acc,init cp(i) in ks

Lemma: cp-kinds_wf
[cp:ClassProgram(Top)]. (cp-kinds(cp) ∈ i:{i:Id| (i ∈ cp-domain(cp))}  ⟶ ({k:Knd| ↑hasloc(k;i)}  List))

Definition: cp-ktype
cp-ktype(cp;i;k) ==  let A,ks,typ,h,acc,init cp(i) in typ k

Lemma: cp-ktype_wf
[cp:ClassProgram(Top)]. ∀[i:{i:Id| (i ∈ cp-domain(cp))} ]. ∀[k:{k:Knd| (k ∈ cp-kinds(cp) i)} ].
  (cp-ktype(cp;i;k) ∈ Type)

Definition: cp-decls
cp-decls(cp) ==  <cp-domain(cp), λi.⊗, λi.mk_fpf(cp-kinds(cp) i;λk.cp-ktype(cp;i;k))>

Lemma: cp-decls_wf
[cp:ClassProgram(Top)]. (cp-decls(cp) ∈ DeclSet)

Definition: cp-state-type
cp-state-type(cp;i) ==  if i ∈ dom(cp) then let A,ks,typ,h,acc,init cp(i) in else Void fi 

Lemma: cp-state-type_wf
[cp:ClassProgram(Top)]. ∀[i:Id].  (cp-state-type(cp;i) ∈ Type)

Definition: cp-test
cp-test(cp;i) ==  let A,ks,typ,h,acc,init cp(i) in h

Lemma: cp-test_wf
[T:Type]. ∀[cp:ClassProgram(T)]. ∀[i:{i:Id| (i ∈ cp-domain(cp))} ].
  (cp-test(cp;i) ∈ k:{k:Knd| (k ∈ cp-kinds(cp) i)}  ⟶ cp-ktype(cp;i;k) ⟶ cp-state-type(cp;i) ⟶ (T Top))

Definition: es-LnkTag-deq
es-LnkTag-deq ==  product-deq(IdLnk;Id;IdLnkDeq;IdDeq)

Lemma: es-LnkTag-deq_wf
es-LnkTag-deq ∈ EqDecider(IdLnk × Id)

Definition: add-graph-decls
add-graph-decls(dd;G;T;a;b) ==  let S,ds,da dd in <S, ds, λi.graph-rcvs(S;G;a;b;i) |-fpf-> T ⊕ da i>

Lemma: add-graph-decls_wf
[dd:DeclSet]. ∀[G:Graph(|dd|)]. ∀[T:Type]. ∀[a:Id ⟶ Id ⟶ Id]. ∀[b:Id].  (add-graph-decls(dd;G;T;a;b) ∈ DeclSet)

Lemma: add-graph-decls-declares-tag
dd:DeclSet. ∀G:Graph(|dd|). ∀T:Type. ∀a:Id ⟶ Id ⟶ Id. ∀b:Id.
  (es-decl-set-declares-tag{i:l}(dd;b;T)  es-decl-set-declares-tag{i:l}(add-graph-decls(dd;G;T;a;b);b;T))

Definition: ci-add-graph
ci-add-graph(ci;G;a;b) ==
  let dd,T,f ci in 
  <add-graph-decls(dd;G;T;a;b), T, λx.let i,k,s,v in if graph-rcvset(a;b;|dd|;G;k) then inl else fi   >

Definition: event-ordering+
EO+(Info) ==  EO; "info":es-base-E(self) ⟶ Info

Lemma: event-ordering+_wf
[T:Type]. (EO+(T) ∈ 𝕌')

Lemma: event-ordering+_cumulative
[T:Type]. (EO+(T) ⊆EO+(T))

Lemma: event-ordering+_cumulative2
[T:Type]. (EO+(T) ⊆event_ordering{i':l})

Definition: es-info
info(e) ==  es."info" e

Lemma: event-ordering+_subtype
[T:Type]. (EO+(T) ⊆EO)

Lemma: event-ordering+_subtype_mem
[T:Type]. ∀[x:EO+(T)].  (x ∈ EO)

Lemma: event-ordering+-subtype
[A,B:Type].  EO+(A) ⊆EO+(B) supposing A ⊆B

Lemma: event-ordering+_inc
[T:Type]. (EO+(T) ⊆ EO)

Lemma: eo-restrict_wf_extended
[Info:Type]. ∀[es:EO+(Info)]. ∀[P:E ⟶ 𝔹].  (eo-restrict(es;P) ∈ EO+(Info))

Lemma: eo-reset-dom_wf_extended
[Info:Type]. ∀[es:EO+(Info)]. ∀[d:es-base-E(es) ⟶ 𝔹].  (eo-reset-dom(es;d) ∈ EO+(Info))

Lemma: es-info_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[e:E].  (info(e) ∈ Info)

Definition: mk-extended-eo
mk-extended-eo(type: E;
               domain: dom;
               loc: l;
               info: info;
               causal: R;
               local: locless;
               pred: pred;
               rank: rank) ==
  mk-eo(E;dom;l;R;locless;pred;rank)["info" := info]

Lemma: mk-extended-eo_wf
[Info,E:Type]. ∀[dom:E ⟶ 𝔹]. ∀[l:E ⟶ Id]. ∀[R:E ⟶ E ⟶ ℙ]. ∀[locless:E ⟶ E ⟶ 𝔹]. ∀[pred:E ⟶ E]. ∀[rank:E ⟶ ℕ].
[info:E ⟶ Info].
  mk-extended-eo(type: E;
                 domain: dom;
                 loc: l;
                 info: info;
                 causal: R;
                 local: locless;
                 pred: pred;
                 rank: rank) ∈ EO+(Info) 
  supposing (∀x,y:E.  ((↓y)  rank x < rank y))
  ∧ (∀e:E. ((l (pred e)) (l e) ∈ Id))
  ∧ (∀e:E. (¬↓(pred e)))
  ∧ (∀e,x:E.  ((↓e)  ((l x) (l e) ∈ Id)  ((↓(pred e) e) ∧ (¬↓(pred e) x))))
  ∧ (∀x,y,z:E.  ((↓y)  (↓z)  (↓z)))
  ∧ (∀e1,e2:E.
       (↓e1 e2 ⇐⇒ ↑(e1 locless e2)) ∧ ((¬↓e1 e2)  (¬↓e2 e1)  (e1 e2 ∈ E)) supposing (l e1) (l e2) ∈ Id)

Definition: eo-forward
eo.e ==  eo-restrict(eo;λe'.(e ≤loc e' ∨bbloc(e') loc(e))))

Lemma: eo-forward_wf
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E].  (eo.e ∈ EO+(Info))

Lemma: eo-forward-wf
[eo:EO]. ∀[e:E].  (eo.e ∈ EO)

Lemma: eo-forward-loc
[eo,e,e':Top].  (loc(e') loc(e'))

Lemma: eo-forward-info
[eo,e,e':Top].  (info(e') info(e'))

Lemma: eo-forward-causl
[eo,e,a,b:Top].  ((a < b) (a < b))

Lemma: eo-forward-E
[eo:EO]. ∀[e:E].  (E {e@0:es-base-E(eo)| ↑((es-dom(eo) e@0) ∧b (e ≤loc e@0 ∨bbloc(e@0) loc(e))))} )

Lemma: eo-forward-E-subtype
[eo:EO]. ∀[e:E].  (E ⊆E)

Lemma: eo-forward-E-subtype2
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E].  ({e':E| (loc(e') loc(e) ∈ Id)  e ≤loc e' }  ⊆E)

Lemma: eo-forward-base-E
[eo,e:Top].  (es-base-E(eo.e) es-base-E(eo))

Lemma: eo-forward-base-pred
[eo,e,x:Top].  (pred1(x) pred1(x))

Lemma: strong-subtype-eo-forward-E
[eo:EO]. ∀[e:E].  strong-subtype(E;E)

Lemma: member-eo-forward-E
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e,e':E].  e' ∈ supposing (loc(e') loc(e) ∈ Id)  e ≤loc e' 

Lemma: eo-forward-E-member
[Info:Type]. ∀eo:EO+(Info). ∀e:E. ∀e':E.  ((e' ∈ E) ∧ ((loc(e') loc(e) ∈ Id)  e ≤loc e' ))

Lemma: equal-eo-forward-E
[eo:EO]. ∀[e:E]. ∀[e1,e2:E].  uiff(e1 e2 ∈ E;e1 e2 ∈ E)

Lemma: eo-forward-less
[eo,e,e1,e2:Top].  ((e1 < e2) (e1 < e2))

Lemma: eo-forward-causle
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e,e1,e2:E].
  e1 c≤ e2 ⇐⇒ e1 c≤ e2 supposing ((loc(e1) loc(e) ∈ Id)  e ≤loc e1 ) ∧ ((loc(e2) loc(e) ∈ Id)  e ≤loc e2 )

Lemma: eo-forward-causle-implies
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E]. ∀[e1,e2:E].  (e1 c≤ e2  e1 c≤ e2)

Lemma: eo-forward-le
eo:EO. ∀e:E. ∀a,b:E.  (a ≤loc b  ⇐⇒ a ≤loc )

Lemma: eo-forward-le2
eo:EO. ∀e:E. ∀a,b:E.  (a ≤loc b   a ≤loc )

Lemma: eo-forward-le-subtype
es:EO. ∀e:E. ∀a:E.  ({e1:E| e1 ≤loc }  ⊆{e1:E| e1 ≤loc )

Lemma: eo-forward-locl
[eo,e,a,b:Top].  ((a <loc b) (a <loc b))

Lemma: eo-forward-ble
eo:EO. ∀e:E. ∀a,b:E.  (a ≤loc a ≤loc b)

Lemma: eo-forward-bless
eo:EO. ∀e:E. ∀a,b:E.  (a <loc a <loc b)

Lemma: eo-forward-eq
[eo,e:Top].  (es-eq(eo.e) es-eq(eo))

Lemma: eo-forward-pred
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E]. ∀[e':E].  pred(e') pred(e') ∈ supposing ¬↑first(e')

Lemma: eo-forward-first
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E]. ∀[e':E].  (first(e') if loc(e') loc(e) then e' else first(e') fi )

Lemma: eo-forward-pred?
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E].
  ∀e1:E. (es-pred?(eo.e;e1) if es-eq(eo) e1 then inr ⋅  else es-pred?(eo;e1) fi  ∈ (E?))

Lemma: eo-forward-first-trivial
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e,e':E].  first(e) tt supposing e' e ∈ E

Lemma: eo-forward-first2
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E]. ∀[e':{e':E| e' ≤loc ].  {uiff(↑first(e);e e' ∈ E)}

Lemma: eo-forward-not-first2
[Info:Type]. ∀eo:EO+(Info). ∀e:E. ∀e':{e':E| e' ≤loc .  uiff(¬↑first(e);(e' <loc e))

Lemma: eo-forward-not-first
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e,e':E].  first(e) ff supposing (e' <loc e)

Lemma: eo-forward-trivial
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E].  eo.e eo ∈ EO+(Info) supposing ↑first(e)

Lemma: eo-forward-forward
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e1,e2:E].  eo.e1.e2 eo.e2 ∈ EO+(Info) supposing e1 ≤loc e2 

Lemma: eo-forward-forward2
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e1:E]. ∀[e2:E].  eo.e1.e2 eo.e2 ∈ EO+(Info) supposing loc(e2) loc(e1) ∈ Id

Lemma: assert-eo-forward-first
[Info:Type]. ∀eo:EO+(Info). ∀e:E. ∀e':E.  uiff(↑first(e');(e' e ∈ E) ∨ ((¬(loc(e') loc(e) ∈ Id)) ∧ (↑first(e'))))

Lemma: eo-forward-before
[Info:Type]. ∀[es:EO+(Info)]. ∀[e,b:E].  before(e) filter(λa.b ≤loc a;before(e)) ∈ (E List) supposing b ≤loc 

Lemma: eo-forward-le-before
[Info:Type]. ∀[es:EO+(Info)]. ∀[e,b:E].  ≤loc(e) filter(λa.b ≤loc a;≤loc(e)) ∈ (E List) supposing b ≤loc 

Lemma: eo-forward-split-before
[Info:Type]. ∀[es:EO+(Info)]. ∀[e,x:E].  before(e) (before(x) before(e)) ∈ (E List) supposing x ≤loc 

Lemma: eo-forward-alle-lt
Info:Type. ∀es:EO+(Info). ∀b:E. ∀e:{e:E| b ≤loc .
  ∀[P:{e':E| b ≤loc e'  ∧ (e' <loc e)}  ⟶ ℙ]. (∀e'<e.P[e'] ⇐⇒ ∀e':E. (b ≤loc e'   (e' <loc e)  P[e']))

Lemma: es-init-forward
[Info:Type]. ∀[es:EO+(Info)]. ∀[e',e:E].  es-init(es.e';e) e' ∈ supposing e' ≤loc 

Lemma: eo-forward-interval
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2,e:E].  ([e1, e2] [e1, e2] ∈ (E List)) supposing (e1 ≤loc e2  and e ≤loc e1 )

Lemma: es-closed-open-interval-eq-before
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2:E].  [e1;e2) before(e2) ∈ (E List) supposing e1 ≤loc e2 

Lemma: es-closed-open-interval-decomp-last
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2:E].  [e1;e2) ([e1;pred(e2)) [pred(e2)]) ∈ (E List) supposing (e1 <loc e2)

Lemma: es-closed-open-interval-sorted-by
[Info:Type]. ∀es:EO+(Info). ∀e1,e2:E.  sorted-by(λx,y. (x <loc y);[e1;e2))

Lemma: es-closed-open-interval-forward
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2,e:E].  ([e1;e2) [e1;e2) ∈ (E List)) supposing (e ≤loc e1  and e1 ≤loc e2 )

Lemma: es-closed-open-interval-decomp-mem
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2,e:E].
  ([e1;e2) ([e1;e) [e;e2)) ∈ (E List)) supposing (e1 ≤loc e  and e ≤loc e2 )

Lemma: es-closed-open-interval-decomp-member
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2,e:E].  [e1;e2) ([e1;e) [e;e2)) ∈ (E List) supposing (e ∈ [e1, e2])

Lemma: es-interval-eq-le-before
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2:E].  [e1, e2] = ≤loc(e2) ∈ (E List) supposing e1 ≤loc e2 

Definition: eo-strict-forward
eo>==  eo-restrict(eo;λe'.(e <loc e' ∨bbloc(e') loc(e))))

Lemma: eo-strict-forward_wf
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E].  (eo>e ∈ EO+(Info))

Lemma: eo-strict-forward-loc
[eo,e,e':Top].  (loc(e') loc(e'))

Lemma: eo-strict-forward-info
[eo,e,e':Top].  (info(e') info(e'))

Lemma: eo-strict-forward-E
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E].
  (E {e@0:es-base-E(eo)| ↑((es-dom(eo) e@0) ∧b (e <loc e@0 ∨bbloc(e@0) loc(e))))} )

Lemma: eo-strict-forward-E-subtype
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E].  (E ⊆E)

Lemma: eo-strict-forward-E-subtype2
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E].  ({e':E| (loc(e') loc(e) ∈ Id)  (e <loc e')}  ⊆E)

Lemma: eo-strict-forward-base-E
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E].  (es-base-E(eo>e) es-base-E(eo))

Lemma: member-eo-strict-forward-E
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e,e':E].  e' ∈ supposing (loc(e') loc(e) ∈ Id)  (e <loc e')

Lemma: eo-strict-forward-E-member
[Info:Type]. ∀eo:EO+(Info). ∀e:E. ∀e':E.  ((e' ∈ E) ∧ ((loc(e') loc(e) ∈ Id)  (e <loc e')))

Lemma: equal-eo-strict-forward-E
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E]. ∀[e1,e2:E].  uiff(e1 e2 ∈ E;e1 e2 ∈ E)

Lemma: eo-strict-forward-less
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e,e1:Top].  ∀e2:Top. ((e1 < e2) (e1 < e2))

Lemma: eo-strict-forward-le
[Info:Type]. ∀eo:EO+(Info). ∀e:E. ∀a,b:E.  (a ≤loc b  ⇐⇒ a ≤loc )

Lemma: eo-strict-forward-locl
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e,a,b:Top].  ((a <loc b) (a <loc b))

Lemma: eo-strict-forward-ble
[Info:Type]. ∀eo:EO+(Info). ∀e:E. ∀a,b:E.  (a ≤loc a ≤loc b)

Lemma: eo-strict-forward-bless
[Info:Type]. ∀eo:EO+(Info). ∀e:E. ∀a,b:E.  (a <loc a <loc b)

Lemma: eo-strict-forward-eq
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E].  (es-eq(eo>e) es-eq(eo))

Lemma: eo-strict-forward-pred
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E]. ∀[e':E].  pred(e') pred(e') ∈ supposing ¬↑first(e')

Lemma: eo-strict-forward-pred?
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E].
  ∀e1:E. (es-pred?(eo>e;e1) if loc(e) loc(e1) ∧b (es-eq(eo) pred(e1) e) then inr ⋅  else es-pred?(eo;e1) fi  ∈ (E?))

Lemma: eo-strict-forward-first
[Info:Type]. ∀[eo:EO+(Info)]. ∀[e:E]. ∀[e':E].
  (first(e') if loc(e') loc(e) then es-eq(eo) pred(e') else first(e') fi )

Lemma: eo-strict-forward-before
[Info:Type]. ∀[es:EO+(Info)]. ∀[e,b:E].  before(e) (b, e) ∈ (E List) supposing (b <loc e)

Definition: es-hist
es-hist(es;e1;e2) ==  map(λe.info(e);[e1, e2])

Lemma: es-hist_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2:E].  (es-hist(es;e1;e2) ∈ Info List)

Lemma: member-es-hist
[Info:Type]. ∀es:EO+(Info). ∀e1,e2:E. ∀t:Info.  ((t ∈ es-hist(es;e1;e2)) ⇐⇒ ∃e∈[e1,e2].t info(e) ∈ Info)

Lemma: null-es-hist
[Info:Type]. ∀es:EO+(Info). ∀e1,e2:E.  ↑null(es-hist(es;e1;e2)) ⇐⇒ (e2 <loc e1) supposing loc(e2) loc(e1) ∈ Id

Lemma: es-hist-iseg
[Info:Type]
  ∀es:EO+(Info). ∀e1,e2,e:E.  e ≤loc e2   es-hist(es;e1;e) ≤ es-hist(es;e1;e2) supposing loc(e2) loc(e1) ∈ Id

Lemma: es-hist-partition
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2,e:E].
  (es-hist(es;e1;e2) (es-hist(es;e1;pred(e)) es-hist(es;e;e2)) ∈ (Info List)) supposing (e ≤loc e2  and (e1 <loc e))

Lemma: es-hist-last
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2:E].
  es-hist(es;e1;e2) (es-hist(es;e1;pred(e2)) [info(e2)]) ∈ (Info List) supposing (e1 <loc e2)

Lemma: last-es-hist
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2:E].  last(es-hist(es;e1;e2)) info(e2) supposing e1 ≤loc e2 

Lemma: es-hist-is-append
[Info:Type]
  ∀es:EO+(Info). ∀e1,e2:E. ∀L1,L2:Info List.
    (∃e∈(e1,e2].(es-hist(es;e1;pred(e)) L1 ∈ (Info List)) ∧ (es-hist(es;e;e2) L2 ∈ (Info List))) supposing 
       ((es-hist(es;e1;e2) (L1 L2) ∈ (Info List)) and 
       (L2 [] ∈ (Info List))) and 
       (L1 [] ∈ (Info List))))

Lemma: es-hist-is-concat
[Info:Type]
  ∀es:EO+(Info). ∀LL:Info List List. ∀e1,e2:E.
    ∀L:Info List
      (∃f:ℕ||LL|| 1 ⟶ E
        ((((f 0) e1 ∈ E) ∧ ||LL|| ≤loc e2 )
        c∧ (∀i:ℕ||LL||. (f i <loc (i 1)))
        c∧ ((∀i:ℕ||LL||. (es-hist(es;f i;pred(f (i 1))) LL[i] ∈ (Info List)))
           ∧ (es-hist(es;f ||LL||;e2) L ∈ (Info List))))) supposing 
         ((es-hist(es;e1;e2) (concat(LL) L) ∈ (Info List)) and 
         (L [] ∈ (Info List))) and 
         (∀L∈LL.¬(L [] ∈ (Info List)))) 
    supposing loc(e1) loc(e2) ∈ Id

Lemma: iseg-es-hist
[Info:Type]
  ∀es:EO+(Info). ∀e1,e2:E. ∀L:Info List.
    (L ≤ es-hist(es;e1;e2)  ∃e∈[e1,e2].L es-hist(es;e1;e) ∈ (Info List)) supposing 
       ((¬(L [] ∈ (Info List))) and 
       (loc(e1) loc(e2) ∈ Id))

Lemma: es-hist-one-one
[Info:Type]. ∀[es:EO+(Info)]. ∀[e1,e2,e3:E].
  (e2 e3 ∈ E) supposing ((es-hist(es;e1;e2) es-hist(es;e1;e3) ∈ (Info List)) and e1 ≤loc e3  and e1 ≤loc e2 )

Definition: es-local-embedding
es-local-embedding(Info;eo1;eo2;f) ==
  ∀e:E. ((loc(e) loc(f e) ∈ Id) ∧ (map(λx.info(x);≤loc(e)) map(λx.info(x);≤loc(f e)) ∈ (Info List)))

Lemma: es-local-embedding_wf
[Info:Type]. ∀[eo1,eo2:EO+(Info)]. ∀[f:E ⟶ E].  (es-local-embedding(Info;eo1;eo2;f) ∈ ℙ)

Lemma: es-local-embedding-compose
[Info:Type]. ∀[eo1,eo2,eo3:EO+(Info)]. ∀[f:E ⟶ E]. ∀[g:E ⟶ E].
  (es-local-embedding(Info;eo1;eo2;f)  es-local-embedding(Info;eo2;eo3;g)  es-local-embedding(Info;eo1;eo3;g f))

Definition: es-embedding
(f embeds eo1 into eo2) ==  es-local-embedding(Info;eo1;eo2;f) ∧ (∀e,e':E.  ((e' < e)  (f e' < e)))

Lemma: es-embedding_wf
[Info:Type]. ∀[eo1,eo2:EO+(Info)]. ∀[f:E ⟶ E].  ((f embeds eo1 into eo2) ∈ ℙ)

Definition: es-local-property
es-local-property(i,L.P[i; L];es;e) ==  P[loc(e); map(λx.info(x);≤loc(e))]

Lemma: es-local-property_wf
[Info:Type]. ∀[P:Id ⟶ Info List+ ⟶ ℙ]. ∀[es:EO+(Info)]. ∀[e:E].  (es-local-property(i,L.P[i;L];es;e) ∈ ℙ)

Definition: es-local-relation
es-local-relation(i,j,L1,L2.R[i; j; L1; L2];es;e1;e2) ==
  R[loc(e1); loc(e2); map(λx.info(x);≤loc(e1)); map(λx.info(x);≤loc(e2))]

Lemma: es-local-relation_wf
[Info:Type]. ∀[R:Id ⟶ Id ⟶ Info List+ ⟶ Info List+ ⟶ ℙ]. ∀[es:EO+(Info)]. ∀[e1,e2:E].
  (es-local-relation(i,j,L1,L2.R[i;j;L1;L2];es;e1;e2) ∈ ℙ)

Lemma: embedding-preserves-local-property
[Info:Type]. ∀[P:Id ⟶ Info List+ ⟶ ℙ].
  ∀eo1,eo2:EO+(Info). ∀f:E ⟶ E.
    (es-local-embedding(Info;eo1;eo2;f)
     (∀[e:E]. (es-local-property(i,L.P[i;L];eo1;e) ⇐⇒ es-local-property(i,L.P[i;L];eo2;f e))))

Lemma: embedding-preserves-local-relation
[Info:Type]. ∀[R:Id ⟶ Id ⟶ Info List+ ⟶ Info List+ ⟶ ℙ]. ∀[eo1:EO+(Info)].
  ∀eo2:EO+(Info). ∀f:E ⟶ E.
    (es-local-embedding(Info;eo1;eo2;f)
     (∀[e1,e2:E].
          (es-local-relation(i,j,L1,L2.R[i;j;L1;L2];eo1;e1;e2)
          ⇐⇒ es-local-relation(i,j,L1,L2.R[i;j;L1;L2];eo2;f e1;f e2))))

Definition: es-joint-embedding
es-joint-embedding(Info;eo1;eo2;eo;f;g) ==
  (f embeds eo1 into eo) ∧ (g embeds eo2 into eo) ∧ (∀e:E. ((∃e1:E. (e (f e1) ∈ E)) ∨ (∃e2:E. (e (g e2) ∈ E))))

Lemma: es-joint-embedding_wf
[Info:Type]. ∀[eo1,eo2,eo:EO+(Info)]. ∀[f:E ⟶ E]. ∀[g:E ⟶ E].  (es-joint-embedding(Info;eo1;eo2;eo;f;g) ∈ ℙ)

Definition: es-weak-joint-embedding
es-weak-joint-embedding(Info;eo1;eo2;eo;f;g) ==
  (f embeds eo1 into eo)
  ∧ es-local-embedding(Info;eo2;eo;g)
  ∧ (∀e:E. ((∃e1:E. (e (f e1) ∈ E)) ∨ (∃e2:E. (e (g e2) ∈ E))))
  ∧ (∀x,y:E.  ((x < y)  ((g x < y) ∨ (∃z:E. ((g y) (f z) ∈ E)))))

Lemma: es-weak-joint-embedding_wf
[Info:Type]. ∀[eo1,eo2,eo:EO+(Info)]. ∀[f:E ⟶ E]. ∀[g:E ⟶ E].  (es-weak-joint-embedding(Info;eo1;eo2;eo;f;g) ∈ ℙ)

Definition: causal-invariant
causal-invariant(i,L.P[i; L];a,b,L1,L2.R[a; b; L1; L2]) ==
  λes.∀e:E
        (es-local-property(i,L.P[i; L];es;e)
         (∃e':E. ((e' < e) ∧ es-local-relation(i,j,L1,L2.R[i; j; L1; L2];es;e';e))))

Lemma: causal-invariant_wf
[Info:Type]. ∀[R:Id ⟶ Id ⟶ Info List+ ⟶ Info List+ ⟶ ℙ]. ∀[P:Id ⟶ Info List+ ⟶ ℙ].
  (causal-invariant(i,L.P[i;L];a,b,L1,L2.R[a;b;L1;L2]) ∈ EO+(Info) ⟶ ℙ)

Definition: squash-causal-invariant
squash-causal-invariant(i,L.P[i; L];a,b,L1,L2.R[a; b; L1; L2]) ==
  λes.∀e:E
        (es-local-property(i,L.P[i; L];es;e)
         (↓∃e':E. ((e' < e) ∧ es-local-relation(i,j,L1,L2.R[i; j; L1; L2];es;e';e))))

Lemma: squash-causal-invariant_wf
[Info:Type]. ∀[R:Id ⟶ Id ⟶ Info List+ ⟶ Info List+ ⟶ ℙ]. ∀[P:Id ⟶ Info List+ ⟶ ℙ].
  (squash-causal-invariant(i,L.P[i;L];a,b,L1,L2.R[a;b;L1;L2]) ∈ EO+(Info) ⟶ ℙ)

Lemma: joint-embedding-preserves-causal-invariant
[Info:Type]. ∀[R:Id ⟶ Id ⟶ Info List+ ⟶ Info List+ ⟶ ℙ]. ∀[P:Id ⟶ Info List+ ⟶ ℙ].
  ∀eo1,eo2,eo:EO+(Info). ∀f:E ⟶ E. ∀g:E ⟶ E.
    (es-joint-embedding(Info;eo1;eo2;eo;f;g)
     (causal-invariant(i,L.P[i;L];a,b,L1,L2.R[a;b;L1;L2]) eo1)
     (causal-invariant(i,L.P[i;L];a,b,L1,L2.R[a;b;L1;L2]) eo2)
     (causal-invariant(i,L.P[i;L];a,b,L1,L2.R[a;b;L1;L2]) eo))

Lemma: weak-joint-embedding-preserves-causal-invariant
[Info:Type]. ∀[R:Id ⟶ Id ⟶ Info List+ ⟶ Info List+ ⟶ ℙ]. ∀[P:Id ⟶ Info List+ ⟶ ℙ].
  ∀eo1,eo2,eo:EO+(Info). ∀f:E ⟶ E. ∀g:E ⟶ E.
    (es-weak-joint-embedding(Info;eo1;eo2;eo;f;g)
     (causal-invariant(i,L.P[i;L];a,b,L1,L2.R[a;b;L1;L2]) eo1)
     (causal-invariant(i,L.P[i;L];a,b,L1,L2.R[a;b;L1;L2]) eo2)
     (causal-invariant(i,L.P[i;L];a,b,L1,L2.R[a;b;L1;L2]) eo))

Lemma: weak-joint-embedding-preserves-squash-causal-invariant
[Info:Type]. ∀[R:Id ⟶ Id ⟶ Info List+ ⟶ Info List+ ⟶ ℙ]. ∀[P:Id ⟶ Info List+ ⟶ ℙ].
  ∀eo1,eo2,eo:EO+(Info). ∀f:E ⟶ E. ∀g:E ⟶ E.
    (es-weak-joint-embedding(Info;eo1;eo2;eo;f;g)
     (squash-causal-invariant(i,L.P[i;L];a,b,L1,L2.R[a;b;L1;L2]) eo1)
     (squash-causal-invariant(i,L.P[i;L];a,b,L1,L2.R[a;b;L1;L2]) eo2)
     (squash-causal-invariant(i,L.P[i;L];a,b,L1,L2.R[a;b;L1;L2]) eo))

Definition: eclass
EClass(A[eo; e]) ==  eo:EO+(Info) ⟶ e:E ⟶ bag(A[eo; e])

Lemma: eclass_wf
[T:Type]. ∀[A:es:EO+(T) ⟶ E ⟶ Type].  (EClass(A[es;e]) ∈ 𝕌')

Lemma: eclass-ext
[T:Type]. ∀[A:es:EO+(T) ⟶ E ⟶ Type]. ∀[X,Y:EClass(A[es;e])].
  Y ∈ EClass(A[es;e]) supposing ∀es:EO+(T). ∀e:E.  ((X es e) (Y es e) ∈ bag(A[es;e]))

Lemma: dep-eclass_subtype_rel
[T:Type]. ∀[A,B:es:EO+(T) ⟶ e:E ⟶ Type].
  EClass(A[es;e]) ⊆EClass(B[es;e]) supposing ∀es:EO+(T). ∀e:E.  (A[es;e] ⊆B[es;e])

Lemma: dep-eclass_subtype_rel2
[T:Type]. ∀[A:EO+(T) ⟶ Type]. ∀[B:Type].  EClass(A[es]) ⊆EClass(B) supposing ∀eo:EO+(T). (A[eo] ⊆B)

Lemma: eclass_subtype_rel
[T,A,B:Type].  EClass(A) ⊆EClass(B) supposing A ⊆B

Definition: class-ap
X(e) ==  es e

Lemma: class-ap_wf
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[X:EClass(T)].  (X(e) ∈ bag(T))

Definition: member-eclass
e ∈b ==  ¬b(#(X es e) =z 0)

Lemma: member-eclass_wf
[T,U:Type]. ∀[X:EClass(U)]. ∀[es:EO+(T)]. ∀[e:E].  (e ∈b X ∈ 𝔹)

Definition: class-le-before
class-le-before(X;es;e) ==  ⋃e'∈≤loc(e).X es e'

Lemma: class-le-before_wf
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E].  (class-le-before(X;es;e) ∈ bag(T))

Definition: class-output
class-output(X;es;bg) ==  ⋃e∈bg.class-le-before(X;es;e)

Lemma: class-output_wf
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[bg:bag(E)].  (class-output(X;es;bg) ∈ bag(T))

Definition: class-output-support
class-output-support(es;bg) ==  ⋃e∈bg.≤loc(e)

Lemma: class-output-support_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[bg:bag(E)].  (class-output-support(es;bg) ∈ bag(E))

Lemma: class-output-eq
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[bg:bag(E)].
  (class-output(X;es;bg) = ⋃e∈class-output-support(es;bg).X es e ∈ bag(T))

Lemma: class-output-support-no-repeats
[Info:Type]. ∀[es:EO+(Info)]. ∀[bg:bag(E)].
  (bag-no-repeats(E;class-output-support(es;bg))) supposing 
     (bag-no-repeats(E;bg) and 
     (∀e1,e2:E.  (e1 ↓∈ bg  e2 ↓∈ bg  (e1 <loc e2)))))

Definition: classrel
This is the fundamental logical relation for 
"event-classes" (aka event-handlers, aka functional processes).
(X of type ⌜EClass(T)⌝).
It says that in event-ordering es, at event e, is in the bag of outputs
of X.⋅

v ∈ X(e) ==  v ↓∈ es e

Lemma: classrel_wf
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:T].  (v ∈ X(e) ∈ ℙ)

Lemma: classrel-evidence
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:T].  ⋅ ∈ v ∈ X(e) supposing v ∈ X(e)

Lemma: eclass-ext-classrel
[Info,T:Type]. ∀[X,Y:EClass(T)].
  uiff(X Y ∈ EClass(T);∀es:EO+(Info). ∀e:E. ∀v:T.  (v ∈ X(e) ⇐⇒ v ∈ Y(e))) 
  supposing ∀es:EO+(Info). ∀e:E.  ((#(X es e) ≤ 1) ∧ (#(Y es e) ≤ 1))

Lemma: classrel-implies-member
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:T].  ↑e ∈b supposing v ∈ X(e)

Lemma: member-implies-classrel
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E].  ↓∃v:T. v ∈ X(e) supposing ↑e ∈b X

Lemma: assert-member-eclass
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E].  (↑e ∈b ⇐⇒ ↓∃v:T. v ∈ X(e))

Lemma: member-eclass-iff-size
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E].  (↑e ∈b ⇐⇒ 0 < #(X es e))

Lemma: member-eclass-iff-non-empty
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E].  (↑e ∈b ⇐⇒ ¬((X es e) {} ∈ bag(T)))

Lemma: member-eclass-iff-size1
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E].  (↑e ∈b ⇐⇒ 1 ≤ #(X es e))

Definition: consistent-class
any x,y from satisfy R[x; y] ==  ∀e1,e2:E. ∀v1,v2:T.  (v1 ∈ X(e1)  v2 ∈ X(e2)  R[v1; v2])

Lemma: consistent-class_wf
[Info,T:Type]. ∀[R:T ⟶ T ⟶ ℙ]. ∀[X:EClass(T)]. ∀[es:EO+(Info)].  (any x,y from satisfy R[x;y] ∈ ℙ)

Definition: correct-consistent-class
any x,y from satisfy
R[x; y]
at locations i.Correct[i] ==
  ∀e1,e2:E.  (Correct[loc(e1)]  Correct[loc(e2)]  (∀v1,v2:T.  (v1 ∈ X(e1)  v2 ∈ X(e2)  R[v1; v2])))

Lemma: correct-consistent-class_wf
[Correct:Id ⟶ ℙ]. ∀[Info,T:Type]. ∀[R:T ⟶ T ⟶ ℙ]. ∀[X:EClass(T)]. ∀[es:EO+(Info)].
  (any x,y from satisfy
   R[x;y]
   at locations i.Correct[i] ∈ ℙ)

Definition: causal-class-relation
for every in there is an
earlier event  with info=b such that
R[a; b] ==
  ∀e:E. ∀a:A.  (a ∈ X(e)  (↓∃e':E. ((e' < e) ∧ R[a; info(e')])))

Lemma: causal-class-relation_wf
[Info,A:Type]. ∀[R:A ⟶ Info ⟶ ℙ]. ∀[X:EClass(A)]. ∀[es:EO+(Info)].
  (for every in there is an
   earlier event  with info=b such that
   R[a;b] ∈ ℙ)

Definition: correct-causal-class-relation
for every in at location s.t. Correct[i] there is an earlier event with info=b  such that R[a; b] ==
  ∀e:E. (Correct[loc(e)]  (∀a:A. (a ∈ X(e)  (↓∃e':E. ((e' < e) ∧ R[a; info(e')])))))

Lemma: correct-causal-class-relation_wf
[Correct:Id ⟶ ℙ]. ∀[Info,A:Type]. ∀[R:A ⟶ Info ⟶ ℙ]. ∀[X:EClass(A)]. ∀[es:EO+(Info)].
  (for every in at location s.t. Correct[i] there is an earlier event with info=b  such that R[a;b] ∈ ℙ)

Lemma: squash-classrel
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:T].  uiff(↓v ∈ X(e);v ∈ X(e))

Lemma: decidable__classrel
[Info,T:Type].  ((∀x,y:T.  Dec(x y ∈ T))  (∀X:EClass(T). ∀es:EO+(Info). ∀e:E. ∀v:T.  Dec(v ∈ X(e))))

Lemma: decidable__exists_bag-member
[T:Type]. ∀b:bag(T). Dec(↓∃x:T. x ↓∈ b)

Lemma: decidable__exists_classrel
[Info,T:Type].  ∀X:EClass(T). ∀es:EO+(Info). ∀e:E.  Dec(↓∃v:T. v ∈ X(e))

Lemma: decidable__exists-classrel-between1
[Info,T:Type].  ∀X:EClass(T). ∀es:EO+(Info). ∀e1,e2:E.  Dec(∃e:E. (e1 ≤loc e  ∧ (e <loc e2) ∧ (↓∃v:T. v ∈ X(e))))

Lemma: decidable__exists-classrel-between3
[Info,T:Type].  ∀X:EClass(T). ∀es:EO+(Info). ∀e1,e2:E.  Dec(∃e:E. ((e1 <loc e) ∧ e ≤loc e2  ∧ (↓∃v:T. v ∈ X(e))))

Lemma: decidable__exists-last-classrel-between3
[Info,T:Type].
  ∀X:EClass(T). ∀es:EO+(Info). ∀e1,e2:E.
    Dec(∃e:E
         ((e1 <loc e)
         ∧ e ≤loc e2 
         ∧ (↓∃v:T. v ∈ X(e))
         ∧ (∀e'':E. ((e <loc e'')  e'' ≤loc e2   (∀x:T. x ∈ X(e'')))))))

Definition: disjoint-classrel
disjoint-classrel(es;A;X;B;Y) ==  ∀e:E. ((∀a:A. a ∈ X(e))) ∨ (∀b:B. b ∈ Y(e))))

Lemma: disjoint-classrel_wf
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)].  (disjoint-classrel(es;A;X;B;Y) ∈ ℙ)

Lemma: disjoint-classrel-symm
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)].
  (disjoint-classrel(es;B;Y;A;X)  disjoint-classrel(es;A;X;B;Y))

Definition: es-total-class
es-total-class(es;X) ==  ∀e:E. (1 ≤ #(X(e)))

Lemma: es-total-class_wf
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)].  (es-total-class(es;X) ∈ ℙ)

Definition: es-sv-class
es-sv-class(es;X) ==  ∀e:E. (#(X es e) ≤ 1)

Lemma: es-sv-class_wf
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)].  (es-sv-class(es;X) ∈ ℙ)

Definition: single-valued-classrel
single-valued-classrel(es;X;T) ==  ∀e:E. ∀v1,v2:T.  (v1 ∈ X(e)  v2 ∈ X(e)  (v1 v2 ∈ T))

Lemma: single-valued-classrel_wf
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)].  (single-valued-classrel(es;X;T) ∈ ℙ)

Lemma: single-valued-classrel-implies-bag
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)]. ∀[e:E].
  (single-valued-classrel(es;X;T)  single-valued-bag(X es e;T))

Definition: single-valued-classrel-all
single-valued-classrel-all{i:l}(Info;T;X) ==  ∀es:EO+(Info). single-valued-classrel(es;X;T)

Lemma: single-valued-classrel-all_wf
[Info,T:Type]. ∀[X:EClass(T)].  (single-valued-classrel-all{i:l}(Info;T;X) ∈ ℙ')

Lemma: single-valued-classrel-all-implies-bag
[Info,T:Type]. ∀[X:EClass(T)].
  ∀[es:EO+(Info)]. ∀[e:E].  single-valued-bag(X es e;T) supposing single-valued-classrel-all{i:l}(Info;T;X)

Definition: es-functional-class
is functional ==  single-valued-classrel(es;X;T) ∧ es-total-class(es;X)

Lemma: es-functional-class_wf
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)].  (X is functional ∈ ℙ)

Definition: es-functional-class-at
is functional at ==  single-valued-classrel(es;X;T) ∧ (↑e ∈b X)

Lemma: es-functional-class-at_wf
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[X:EClass(T)].  (X is functional at e ∈ ℙ)

Lemma: es-functional-class-implies-at
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)].  ∀[e:E]. is functional at supposing is functional

Definition: classfun
X(e) ==  sv-bag-only(X eo e)

Lemma: classfun_wf
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)].  ∀[e:E]. (X(e) ∈ T) supposing is functional

Lemma: bag-member-classfun
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)].  ∀[e:E]. X(e) ↓∈ es supposing is functional

Lemma: classrel-classfun
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)].  ∀[e:E]. ∀[v:T].  uiff(v ∈ X(e);v X(e) ∈ T) supposing is functional

Definition: classfun-res
X@e ==  X(e)

Lemma: classfun-res_wf
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)]. ∀[e:E].
  (X@e ∈ T) supposing (single-valued-classrel(es;X;T) and (↑e ∈b X))

Lemma: bag-member-classfun-res
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)]. ∀[e:E].
  (X@e ↓∈ es e) supposing (single-valued-classrel(es;X;T) and (↑e ∈b X))

Lemma: classrel-classfun-res
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)]. ∀[e:E]. ∀[v:T].
  (uiff(v ∈ X(e);v X@e ∈ T)) supposing (single-valued-classrel(es;X;T) and (↑e ∈b X))

Lemma: classrel-classfun-res-alt1
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)]. ∀[e:E]. ∀[v:T].
  uiff(v ∈ X(e);if e ∈b then X@e ∈ else False fi supposing single-valued-classrel(es;X;T)

Lemma: classrel-classfun-res-alt2
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)]. ∀[e:E]. ∀[v:T].
  uiff(v ∈ X(e);(↑e ∈b X) ∧ (v X@e ∈ T)) supposing single-valued-classrel(es;X;T)

Lemma: classrel-implies-classfun-res
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)]. ∀[e:E]. ∀[v:T].
  (v X@e ∈ T) supposing (v ∈ X(e) and single-valued-classrel(es;X;T))

Lemma: es-sv-class-implies-single-valued-classrel
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)].  single-valued-classrel(es;X;T) supposing es-sv-class(es;X)

Lemma: decidable__exists-single-valued-bag
[T:Type]. ∀b:bag(T). (single-valued-bag(b;T)  Dec(∃v:T. v ↓∈ b))

Lemma: decidable__exists-single-valued-classrel
[Info,T:Type].  ∀X:EClass(T). ∀es:EO+(Info).  (single-valued-classrel(es;X;T)  (∀e:E. Dec(∃v:T. v ∈ X(e))))

Lemma: decidable__exists-classrel-between1-sv
[Info,T:Type].
  ∀X:EClass(T). ∀es:EO+(Info).
    (single-valued-classrel(es;X;T)  (∀e1,e2:E.  Dec(∃e:E. (e1 ≤loc e  ∧ (e <loc e2) ∧ (∃v:T. v ∈ X(e))))))

Lemma: decidable__exists-classrel-between3-sv
[Info,T:Type].
  ∀X:EClass(T). ∀es:EO+(Info).
    (single-valued-classrel(es;X;T)  (∀e1,e2:E.  Dec(∃e:E. ((e1 <loc e) ∧ e ≤loc e2  ∧ (∃v:T. v ∈ X(e))))))

Lemma: decidable__exists-last-classrel-between3-sv
[Info,T:Type].
  ∀X:EClass(T). ∀es:EO+(Info).
    (single-valued-classrel(es;X;T)
     (∀e1,e2:E.
          Dec(∃e:E
               ((e1 <loc e)
               ∧ e ≤loc e2 
               ∧ (∃v:T. v ∈ X(e))
               ∧ (∀e'':E. ((e <loc e'')  e'' ≤loc e2   (∀x:T. x ∈ X(e'')))))))))

Definition: iterated_classrel
iterated_classrel(es;S;A;f;init;X;e;v) ==
  fix((λiterated_classrel,e,v. (↓∃z:S
                                  (if first(e) then z ↓∈ init loc(e) else iterated_classrel pred(e) fi 
                                  ∧ ((∃a:A. (a ∈ X(e) ∧ (v (f z) ∈ S))) ∨ ((∀a:A. a ∈ X(e))) ∧ (v z ∈ S))))))) 
  
  v

Lemma: iterated_classrel_wf
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:S].
  (iterated_classrel(es;S;A;f;init;X;e;v) ∈ ℙ)

Lemma: sq_stable__iterated_classrel
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:S].
  SqStable(iterated_classrel(es;S;A;f;init;X;e;v))

Lemma: squash-iterated_classrel
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:S].
  uiff(↓iterated_classrel(es;S;A;f;init;X;e;v);iterated_classrel(es;S;A;f;init;X;e;v))

Lemma: iterated_classrel-single-val
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)].
  ∀es:EO+(Info)
    (single-valued-classrel(es;X;A)
     (∀e:E
          (single-valued-bag(init loc(e);S)
           (∀v1,v2:S.
                (iterated_classrel(es;S;A;f;init;X;e;v1)
                 iterated_classrel(es;S;A;f;init;X;e;v2)
                 (v1 v2 ∈ S))))))

Lemma: iterated_classrel-exists
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E].
  ↓∃v:S. iterated_classrel(es;S;A;f;init;X;e;v) supposing ↓∃s:S. s ↓∈ init loc(e)

Lemma: iterated_classrel-exists-iff
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E].
  uiff(↓∃s:S. s ↓∈ init loc(e);↓∃v:S. iterated_classrel(es;S;A;f;init;X;e;v))

Lemma: decidable__exists_iterated_classrel
[Info,A,S:Type].
  ∀init:Id ⟶ bag(S). ∀f:A ⟶ S ⟶ S. ∀X:EClass(A). ∀es:EO+(Info). ∀e:E.
    (single-valued-classrel(es;X;A)
     single-valued-bag(init loc(e);S)
     Dec(∃v:S. iterated_classrel(es;S;A;f;init;X;e;v)))

Lemma: decidable__exists-iterated-classrel-between3-sv
[Info,T,S:Type].
  ∀init:Id ⟶ bag(S). ∀f:T ⟶ S ⟶ S. ∀X:EClass(T). ∀es:EO+(Info). ∀P:T ⟶ S ⟶ ℙ. ∀e1,e2:E.
    (single-valued-classrel(es;X;T)
     single-valued-bag(init loc(e1);S)
     (∀v:T. ∀s:S.  Dec(P[v;s]))
     Dec(∃e:E
            ∃s:S
             ((e1 <loc e) ∧ e ≤loc e2  ∧ iterated_classrel(es;S;T;f;init;X;pred(e);s) ∧ (∃v:T. (v ∈ X(e) ∧ P[v;s])))))

Lemma: iterated_classrel_invariant1
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)].
  ∀es:EO+(Info)
    ∀[P:S ⟶ ℙ]
      ((∀s:S. Dec(P[s]))
       (∀e:E. ∀v:S.
            ((∀s:S. (s ↓∈ init loc(e)  P[s]))
             (∀a:A. ∀s:S.  (P[s]  P[f s]))
             iterated_classrel(es;S;A;f;init;X;e;v)
             P[v])))

Lemma: iterated_classrel_invariant2
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)].
  ∀es:EO+(Info)
    ∀[P:S ⟶ ℙ]
      ((∀s:S. SqStable(P[s]))
       (∀e:E. ∀v:S.
            ((∀s:S. (s ↓∈ init loc(e)  P[s]))
             (∀a:A. ∀e':E.  (e' ≤loc e   a ∈ X(e')  (∀s:S. (P[s]  P[f s]))))
             iterated_classrel(es;S;A;f;init;X;e;v)
             P[v])))

Lemma: iterated_classrel_trans1
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)].
  ∀es:EO+(Info)
    (single-valued-classrel(es;X;A)
     (∀[R:S ⟶ S ⟶ ℙ]
          ((∀x,y:S.  Dec(R[x;y]))
           Trans(S;x,y.R[x;y])
           (∀a:A. ∀s:S.  R[s;f s])
           (∀e1,e2:E.
                (single-valued-bag(init loc(e1);S)
                 (e1 <loc e2)
                 (∀v1,v2:S.
                      (iterated_classrel(es;S;A;f;init;X;e1;v1)
                       iterated_classrel(es;S;A;f;init;X;e2;v2)
                       (((∃e:E. ((e1 <loc e) ∧ e ≤loc e2  ∧ (∃a:A. a ∈ X(e))))  R[v1;v2])
                         ∧ ((∀e:E. ((e1 <loc e)  e ≤loc e2   (∀a:A. a ∈ X(e)))))  (v1 v2 ∈ S))))))))))

Lemma: iterated_classrel_trans2
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)].
  ∀es:EO+(Info)
    (single-valued-classrel(es;X;A)
     (∀[R:S ⟶ S ⟶ ℙ]
          ((∀x,y:S.  SqStable(R[x;y]))
           Trans(S;x,y.R[x;y])
           (∀a:A. ∀e:E.  (a ∈ X(e)  (∀s:S. R[s;f s])))
           (∀e1,e2:E.
                (single-valued-bag(init loc(e1);S)
                 (e1 <loc e2)
                 (∀v1,v2:S.
                      (iterated_classrel(es;S;A;f;init;X;e1;v1)
                       iterated_classrel(es;S;A;f;init;X;e2;v2)
                       (((∃e:E. ((e1 <loc e) ∧ e ≤loc e2  ∧ (∃a:A. a ∈ X(e))))  R[v1;v2])
                         ∧ ((∀e:E. ((e1 <loc e)  e ≤loc e2   (∀a:A. a ∈ X(e)))))  (v1 v2 ∈ S))))))))))

Lemma: iterated_classrel_trans3
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)].
  ∀es:EO+(Info)
    (single-valued-classrel(es;X;A)
     (∀[R:S ⟶ S ⟶ ℙ]
          ((∀x,y:S.  SqStable(R[x;y]))
           Trans(S;x,y.R[x;y])
           (∀e1,e2:E.
                ((∀a:A. ∀e:E.
                    ((e1 <loc e)
                     e ≤loc e2 
                     a ∈ X(e)
                     (∀s:S. (iterated_classrel(es;S;A;f;init;X;pred(e);s)  R[s;f s]))))
                 single-valued-bag(init loc(e1);S)
                 (e1 <loc e2)
                 (∀v1,v2:S.
                      (iterated_classrel(es;S;A;f;init;X;e1;v1)
                       iterated_classrel(es;S;A;f;init;X;e2;v2)
                       (((∃e:E. ((e1 <loc e) ∧ e ≤loc e2  ∧ (∃a:A. a ∈ X(e))))  R[v1;v2])
                         ∧ ((∀e:E. ((e1 <loc e)  e ≤loc e2   (∀a:A. a ∈ X(e)))))  (v1 v2 ∈ S))))))))))

Lemma: iterated_classrel_progress
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)].
  ∀es:EO+(Info). ∀R:S ⟶ S ⟶ ℙ. ∀P:A ⟶ S ⟶ ℙ. ∀e1,e2:E. ∀v1,v2:S.
    (single-valued-classrel(es;X;A)
     (∀a:A. ∀s:S.  Dec(P[a;s]))
     (∀x,y:S.  SqStable(R[x;y]))
     Trans(S;x,y.R[x;y])
     (∀a:A. ∀e:E. ∀s:S.
          ((e1 <loc e)
           e ≤loc e2 
           a ∈ X(e)
           iterated_classrel(es;S;A;f;init;X;pred(e);s)
           ((P[a;s]  R[s;f s]) ∧ ((¬P[a;s])  (s (f s) ∈ S)))))
     single-valued-bag(init loc(e1);S)
     (e1 <loc e2)
     iterated_classrel(es;S;A;f;init;X;e1;v1)
     iterated_classrel(es;S;A;f;init;X;e2;v2)
     (((∃e:E
           ∃s:S
            ((e1 <loc e) ∧ e ≤loc e2  ∧ iterated_classrel(es;S;A;f;init;X;pred(e);s) ∧ (∃a:A. (a ∈ X(e) ∧ P[a;s]))))
        R[v1;v2])
       ∧ ((∀e:E. ∀s:S.
             ((e1 <loc e)
              e ≤loc e2 
              iterated_classrel(es;S;A;f;init;X;pred(e);s)
              (∀a:A. ((¬a ∈ X(e)) ∨ P[a;s])))))
          (v1 v2 ∈ S))))

Lemma: iterated_classrel_mem
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)].
  ∀es:EO+(Info). ∀R:A ⟶ S ⟶ S ⟶ ℙ. ∀e1,e2:E. ∀v1,v2:S. ∀a:A.
    (single-valued-classrel(es;X;A)
     single-valued-bag(init loc(e1);S)
     (∀s1,s2:S. ∀a:A.  SqStable(R[a;s1;s2]))
     (∀a1,a2:A. ∀s:S. ∀e,e':E.
          (e1 ≤loc 
           (e <loc e')
           e' ≤loc e2 
           a1 ∈ X(e)
           iterated_classrel(es;S;A;f;init;X;e;s)
           a2 ∈ X(e')
           R[a1;s;f a2 s]))
     (∀a1,a2:A. ∀s1,s2:S. ∀e1,e2:E.
          ((e1 <loc e2)
           a1 ∈ X(e1)
           iterated_classrel(es;S;A;f;init;X;e1;s1)
           a2 ∈ X(e2)
           iterated_classrel(es;S;A;f;init;X;pred(e2);s2)
           R[a1;s1;s2]
           R[a1;s1;f a2 s2]))
     (e1 <loc e2)
     a ∈ X(e1)
     iterated_classrel(es;S;A;f;init;X;e1;v1)
     iterated_classrel(es;S;A;f;init;X;e2;v2)
     (((∃e:E. ((e1 <loc e) ∧ e ≤loc e2  ∧ (∃a:A. a ∈ X(e))))  R[a;v1;v2])
       ∧ ((∀e:E. ((e1 <loc e)  e ≤loc e2   (∀a:A. a ∈ X(e)))))  (v1 v2 ∈ S))))

Definition: prior_iterated_classrel
s ∈ prior(X*(f,init,e)) ==
  ((↑first(e)) ∧ s ↓∈ init loc(e)) ∨ ((¬↑first(e)) ∧ iterated_classrel(es;S;A;f;init;X;pred(e);s))

Lemma: prior_iterated_classrel_wf
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[s:S].
  (s ∈ prior(X*(f,init,e)) ∈ ℙ)

Lemma: iterated_classrel_invariant3
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[P:S ⟶ ℙ].
  ((∀s:S. SqStable(P[s]))
   (∀e:E. ∀v:S.
        ((∀s:S. (s ↓∈ init loc(e)  P[s]))
         (∀a:A. ∀e':E.  (e' ≤loc e   a ∈ X(e')  (∀s:S. (s ∈ prior(X*(f,init,e'))  P[s]  P[f s]))))
         iterated_classrel(es;S;A;f;init;X;e;v)
         P[v])))

Lemma: iterated_classrel_mem2
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)].
  ∀es:EO+(Info). ∀R:A ⟶ S ⟶ S ⟶ ℙ. ∀e1,e2:E. ∀v1,v2:S. ∀a:A.
    (single-valued-classrel(es;X;A)
     single-valued-bag(init loc(e1);S)
     (∀s1,s2:S. ∀a:A.  SqStable(R[a;s1;s2]))
     (∀a:A. ∀s:S. ∀e:E.  (e1 ≤loc e   e ≤loc e2   a ∈ X(e)  s ∈ prior(X*(f,init,e))  R[a;s;f s]))
     (∀a1,a2:A. ∀s1,s2:S. ∀e,e':E.
          (e1 ≤loc 
           (e <loc e')
           e' ≤loc e2 
           a1 ∈ X(e)
           s1 ∈ prior(X*(f,init,e))
           a2 ∈ X(e')
           iterated_classrel(es;S;A;f;init;X;pred(e');s2)
           R[a1;s1;s2]
           R[a1;s1;f a2 s2]))
     e1 ≤loc e2 
     a ∈ X(e1)
     v1 ∈ prior(X*(f,init,e1))
     iterated_classrel(es;S;A;f;init;X;e2;v2)
     R[a;v1;v2])

Definition: iterated-classrel
iterated-classrel(es;S;A;f;init;X;e;v) ==
  fix((λiterated-classrel,e,v. ∃z:S
                                (if first(e) then z ↓∈ init loc(e) else iterated-classrel pred(e) fi 
                                ∧ ((∃a:A. (a ∈ X(e) ∧ (v (f z) ∈ S))) ∨ ((∀a:A. a ∈ X(e))) ∧ (v z ∈ S)))))) 
  
  v

Lemma: iterated-classrel_wf
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:S].
  (iterated-classrel(es;S;A;f;init;X;e;v) ∈ ℙ)

Lemma: iterated-classrel-iff
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:S].
  uiff(iterated_classrel(es;S;A;f;init;X;e;v);↓iterated-classrel(es;S;A;f;init;X;e;v))

Definition: prior-iterated-classrel
prior-iterated-classrel(es;A;S;s;X;f;init;e) ==
  ((↑first(e)) ∧ s ↓∈ init loc(e)) ∨ ((¬↑first(e)) ∧ iterated-classrel(es;S;A;f;init;X;pred(e);s))

Lemma: prior-iterated-classrel_wf
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[s:S].
  (prior-iterated-classrel(es;A;S;s;X;f;init;e) ∈ ℙ)

Lemma: iterated-classrel-single-val
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v1,v2:S].
  (v1 v2 ∈ S) supposing 
     (iterated-classrel(es;S;A;f;init;X;e;v2) and 
     iterated-classrel(es;S;A;f;init;X;e;v1) and 
     single-valued-bag(init loc(e);S) and 
     single-valued-classrel(es;X;A))

Lemma: iterated-classrel-exists
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)].
  ∀f:A ⟶ S ⟶ S. ∀X:EClass(A). ∀es:EO+(Info). ∀e:E.
    (single-valued-classrel(es;X;A)  (∃s:S. s ↓∈ init loc(e))  (∃v:S. iterated-classrel(es;S;A;f;init;X;e;v)))

Lemma: iterated-classrel-exists-iff
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)].
  ∀f:A ⟶ S ⟶ S. ∀X:EClass(A). ∀es:EO+(Info). ∀e:E.
    (single-valued-classrel(es;X;A)  (∃s:S. s ↓∈ init loc(e) ⇐⇒ ∃v:S. iterated-classrel(es;S;A;f;init;X;e;v)))

Lemma: decidable__exists-iterated-classrel
[Info,A,S:Type].
  ∀init:Id ⟶ bag(S). ∀f:A ⟶ S ⟶ S. ∀X:EClass(A). ∀es:EO+(Info). ∀e:E.
    (single-valued-classrel(es;X;A)
     single-valued-bag(init loc(e);S)
     Dec(∃v:S. iterated-classrel(es;S;A;f;init;X;e;v)))

Lemma: decidable__exists-prior-iterated-classrel
[Info,A,S:Type].
  ∀init:Id ⟶ bag(S). ∀f:A ⟶ S ⟶ S. ∀X:EClass(A). ∀es:EO+(Info). ∀e:E.
    (single-valued-classrel(es;X;A)
     single-valued-bag(init loc(e);S)
     Dec(∃v:S. prior-iterated-classrel(es;A;S;v;X;f;init;e)))

Lemma: sq_stable__single-valued-iterated-classrel
[Info,A,S:Type].
  ∀init:Id ⟶ bag(S). ∀f:A ⟶ S ⟶ S. ∀X:EClass(A). ∀es:EO+(Info). ∀e:E. ∀v:S.
    (single-valued-classrel(es;X;A)
     single-valued-bag(init loc(e);S)
     SqStable(iterated-classrel(es;S;A;f;init;X;e;v)))

Lemma: sq_stable__single-valued-prior-iterated-classrel
[Info,A,S:Type].
  ∀init:Id ⟶ bag(S). ∀f:A ⟶ S ⟶ S. ∀X:EClass(A). ∀es:EO+(Info). ∀e:E. ∀v:S.
    (single-valued-classrel(es;X;A)
     single-valued-bag(init loc(e);S)
     SqStable(prior-iterated-classrel(es;A;S;v;X;f;init;e)))

Lemma: decidable__exists-pred-iterated-classrel-between3-sv
[Info,T,S:Type].
  ∀init:Id ⟶ bag(S). ∀f:T ⟶ S ⟶ S. ∀X:EClass(T). ∀es:EO+(Info). ∀P:T ⟶ S ⟶ ℙ. ∀e1,e2:E.
    (single-valued-classrel(es;X;T)
     single-valued-bag(init loc(e1);S)
     (∀v:T. ∀s:S.  Dec(P[v;s]))
     Dec(∃e:E
            ∃s:S
             ((e1 <loc e) ∧ e ≤loc e2  ∧ iterated-classrel(es;S;T;f;init;X;pred(e);s) ∧ (∃v:T. (v ∈ X(e) ∧ P[v;s])))))

Lemma: iterated-classrel-as-prior
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)].
  ∀es:EO+(Info). ∀e:E.
    ∀[v:S]
      (iterated-classrel(es;S;A;f;init;X;e;v)
      ⇐⇒ ∃z:S
           (prior-iterated-classrel(es;A;S;z;X;f;init;e)
           ∧ ((∃a:A. (a ∈ X(e) ∧ (v (f z) ∈ S))) ∨ ((∀a:A. a ∈ X(e))) ∧ (v z ∈ S)))))

Lemma: iterated-classrel-invariant
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)]. ∀[P:S ⟶ ℙ].
  ∀es:EO+(Info). ∀e:E. ∀v:S.
    ((∀s:S. (s ↓∈ init loc(e)  P[s]))
     (∀a:A. ∀e':E. ∀s:S.
          (e' ≤loc e   a ∈ X(e')  prior-iterated-classrel(es;A;S;s;X;f;init;e')  P[s]  P[f s]))
     iterated-classrel(es;S;A;f;init;X;e;v)
     P[v])

Lemma: iterated-classrel-invariant2
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S].
  ∀X:EClass(A). ∀es:EO+(Info).
    ∀[P:E ⟶ S ⟶ ℙ]
      ∀e:E. ∀v:S.
        ((∀s:S. ∀e':E.
            (e' ≤loc 
             if first(e')
               then s ↓∈ init loc(e')
               else iterated-classrel(es;S;A;f;init;X;pred(e');s) ∧ P[pred(e');s]
               fi 
             if e' ∈b then ∀a:A. (a ∈ X(e')  P[e';f s]) else P[e';s] fi ))
         iterated-classrel(es;S;A;f;init;X;e;v)
         P[e;v])

Lemma: iterated-classrel-trans
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[R:S ⟶ S ⟶ ℙ].
  ∀X:EClass(A). ∀es:EO+(Info). ∀e1,e2:E. ∀v1,v2:S.
    (single-valued-classrel(es;X;A)
     single-valued-bag(init loc(e1);S)
     Trans(S;x,y.R[x;y])
     (∀a:A. ∀e:E.
          ((e1 <loc e)
           e ≤loc e2 
           a ∈ X(e)
           (∀s:S. (iterated-classrel(es;S;A;f;init;X;pred(e);s)  R[s;f s]))))
     (e1 <loc e2)
     iterated-classrel(es;S;A;f;init;X;e1;v1)
     iterated-classrel(es;S;A;f;init;X;e2;v2)
     (((∃e:E. ((e1 <loc e) ∧ e ≤loc e2  ∧ (∃a:A. a ∈ X(e))))  R[v1;v2])
       ∧ ((∀e:E. ((e1 <loc e)  e ≤loc e2   (∀a:A. a ∈ X(e)))))  (v1 v2 ∈ S))))

Lemma: iterated-classrel-progress
[Info,A,S:Type].
  ∀init:Id ⟶ bag(S). ∀f:A ⟶ S ⟶ S. ∀X:EClass(A). ∀es:EO+(Info). ∀R:S ⟶ S ⟶ ℙ. ∀P:A ⟶ S ⟶ ℙ. ∀e1,e2:E. ∀v1,v2:S.
    (single-valued-classrel(es;X;A)
     single-valued-bag(init loc(e1);S)
     (∀a:A. ∀s:S.  Dec(P[a;s]))
     Trans(S;x,y.R[x;y])
     (∀a:A. ∀e:E. ∀s:S.
          ((e1 <loc e)
           e ≤loc e2 
           a ∈ X(e)
           iterated-classrel(es;S;A;f;init;X;pred(e);s)
           ((P[a;s]  R[s;f s]) ∧ ((¬P[a;s])  (s (f s) ∈ S)))))
     (e1 <loc e2)
     iterated-classrel(es;S;A;f;init;X;e1;v1)
     iterated-classrel(es;S;A;f;init;X;e2;v2)
     (((∃e:E
           ∃s:S
            ((e1 <loc e) ∧ e ≤loc e2  ∧ iterated-classrel(es;S;A;f;init;X;pred(e);s) ∧ (∃a:A. (a ∈ X(e) ∧ P[a;s]))))
        R[v1;v2])
       ∧ ((∀e:E. ∀s:S.
             ((e1 <loc e)
              e ≤loc e2 
              iterated-classrel(es;S;A;f;init;X;pred(e);s)
              (∀a:A. ((¬a ∈ X(e)) ∨ P[a;s])))))
          (v1 v2 ∈ S))))

Lemma: iterated-classrel-mem
[Info,A,S:Type]. ∀[init:Id ⟶ bag(S)]. ∀[f:A ⟶ S ⟶ S]. ∀[X:EClass(A)].
  ∀es:EO+(Info). ∀R:A ⟶ S ⟶ S ⟶ ℙ. ∀e1,e2:E. ∀v1,v2:S. ∀a:A.
    (single-valued-classrel(es;X;A)
     single-valued-bag(init loc(e1);S)
     (∀a:A. ∀s:S. ∀e:E.
          (e1 ≤loc e   e ≤loc e2   a ∈ X(e)  prior-iterated-classrel(es;A;S;s;X;f;init;e)  R[a;s;f s]))
     (∀a1,a2:A. ∀s1,s2:S. ∀e,e':E.
          (e1 ≤loc 
           (e <loc e')
           e' ≤loc e2 
           a1 ∈ X(e)
           prior-iterated-classrel(es;A;S;s1;X;f;init;e)
           a2 ∈ X(e')
           iterated-classrel(es;S;A;f;init;X;pred(e');s2)
           R[a1;s1;s2]
           R[a1;s1;f a2 s2]))
     e1 ≤loc e2 
     a ∈ X(e1)
     prior-iterated-classrel(es;A;S;v1;X;f;init;e1)
     iterated-classrel(es;S;A;f;init;X;e2;v2)
     R[a;v1;v2])

Lemma: member-class-le-before
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:T].
  uiff(v ↓∈ class-le-before(X;es;e);↓∃e':E. (e' ≤loc e  ∧ v ∈ X(e')))

Lemma: member-class-output
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[bg:bag(E)]. ∀[v:T].
  uiff(v ↓∈ class-output(X;es;bg);↓∃e:E. (e ↓∈ bg ∧ v ↓∈ class-le-before(X;es;e)))

Lemma: class-output-support-no_repeats
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[bg:bag(E)].
  (bag-no-repeats(E;class-output-support(es;bg))) supposing 
     (bag-no-repeats(E;bg) and 
     (∀e1,e2:E.  (e2 ↓∈ bg  e1 ↓∈ bg  (e1 <loc e2)))))

Lemma: class-output-member-support
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[bg:bag(E)]. ∀[x:T]. ∀[X:EClass(T)].
  ↓∃e:E. (e ↓∈ class-output-support(es;bg) ∧ x ∈ X(e)) supposing x ↓∈ class-output(X;es;bg)

Definition: no-prior-classrel
(no prior to e) ==  ∀e'<e.∀w:A. w ∈ X(e'))

Lemma: no-prior-classrel_wf
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E].  ((no prior to e) ∈ ℙ)

Lemma: sq_stable__no-prior-classrel
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E].  SqStable((no prior to e))

Definition: no-classrel-in-interval
(no between start and e) ==  ∀e'<e.start ≤loc e'   (∀w:A. w ∈ X(e')))

Lemma: no-classrel-in-interval_wf
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[start,e:E].  ((no between start and e) ∈ ℙ)

Lemma: sq_stable__no-classrel-in-interval
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[start,e:E].  SqStable((no between start and e))

Lemma: eo-forward-no-prior-classrel
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[start:E]. ∀[e:E].
  uiff((no prior to e);(no between start and e)) supposing loc(e) loc(start) ∈ Id

Lemma: eo-forward-no-classrel-in-interval
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[start:E]. ∀[e1:E]. ∀[e:E].
  uiff((no between e1 and e);(no between e1 and e)) supposing (loc(e) loc(e1) ∈ Id) ∧ (loc(e1) loc(start) ∈ Id)

Lemma: no-classrel-in-interval-trivial
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E].  (no between and e)

Definition: classRel
classRel(es;T;X;e;v) ==  v ∈ X(e)

Lemma: no-classrel-iff-empty
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E].  uiff(∀v:T. v ∈ X(e));(X es e) {} ∈ bag(T))

Lemma: sq_stable__classrel
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:T].  SqStable(v ∈ X(e))

Definition: inhabited-classrel
inhabited-classrel(eo;T;X;e) ==  ↓∃v:T. v ∈ X(e)

Lemma: inhabited-classrel_wf
[Info,T:Type]. ∀[X:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E].  (inhabited-classrel(es;T;X;e) ∈ ℙ)

Definition: class-loc-bound
class-loc-bound{i:l}(Info;T;X;L) ==  ∀es:EO+(Info). ∀v:T. ∀e:E.  (v ∈ X(e)  loc(e) ↓∈ L)

Lemma: class-loc-bound_wf
[Info,T:Type]. ∀[X:EClass(T)]. ∀[L:bag(Id)].  (class-loc-bound{i:l}(Info;T;X;L) ∈ ℙ')

Definition: loc-bounded-class
LocBounded(T;X) ==  ∃L:bag(Id). class-loc-bound{i:l}(Info;T;X;L)

Lemma: loc-bounded-class_wf
[Info,T:Type]. ∀[X:EClass(T)].  (LocBounded(T;X) ∈ ℙ')

Definition: local-class-predicate
local-class-predicate{i:l}(F;Info;A;X) ==
  ∀es:EO+(Info). ∀e:E.  (X(e) (snd(F loc(e)*(map(λx.info(x);before(e)))(info(e)))) ∈ bag(A))

Lemma: local-class-predicate_wf
[Info,A:Type]. ∀[X:EClass(A)]. ∀[F:Id ⟶ hdataflow(Info;A)].  (local-class-predicate{i:l}(F;Info;A;X) ∈ ℙ')

Lemma: local-class-predicate-property
[Info,A:Type]. ∀[X:EClass(A)]. ∀[F1,F2:Id ⟶ hdataflow(Info;A)].
  (local-class-predicate{i:l}(F2;Info;A;X)) supposing 
     (local-class-predicate{i:l}(F1;Info;A;X) and 
     (∀i:Id. (F1[i] F2[i] ∈ hdataflow(Info;A))))

Lemma: local-class-predicate-property2
[Info,A:Type]. ∀[X1,X2:EClass(A)]. ∀[F:Id ⟶ hdataflow(Info;A)].
  (local-class-predicate{i:l}(F;Info;A;X1)) supposing 
     (local-class-predicate{i:l}(F;Info;A;X2) and 
     (∀es:EO+(Info). ∀e:E.  (X1(e) X2(e) ∈ bag(A))))

Definition: local-class
LocalClass(X) ==
  ∃F:{Id ⟶ hdataflow(Info;A)| (∀es:EO+(Info). ∀e:E.
                                  (X(e) (snd(F loc(e)*(map(λx.info(x);before(e)))(info(e)))) ∈ bag(A)))}

Lemma: local-class_wf
[Info,A:Type]. ∀[X:EClass(A)].  (LocalClass(X) ∈ ℙ')

Lemma: local-class-ap-member
[Info,A,T:Type]. ∀[X:T ⟶ EClass(A)]. ∀[prog:∀x:T. LocalClass(X x)]. ∀[x:T].  (prog x ∈ LocalClass(X x))

Lemma: embedding-preserves-local-class
[Info,A:Type]. ∀[X:EClass(A)].
  (LocalClass(X)
   (∀eo1,eo2:EO+(Info). ∀f:E ⟶ E.
        (es-local-embedding(Info;eo1;eo2;f)  (∀[e:E]. ∀[v:A].  (v ∈ X(e) ⇐⇒ v ∈ X(f e))))))

Definition: implemented-class
implemented-class{i:l}(Info;A) ==  X:EClass(A) × LocalClass(X)

Lemma: implemented-class_wf
[Info,A:Type].  (implemented-class{i:l}(Info;A) ∈ ℙ')

Definition: eo-local-agree
eo-local-agree(Info;eo1;eo2;e1;e2) ==  map(λe.info(e);≤loc(e1)) map(λe.info(e);≤loc(e2)) ∈ (Info List)

Lemma: eo-local-agree_wf
[Info:Type]. ∀[eo1,eo2:EO+(Info)]. ∀[e1:E]. ∀[e2:E].  (eo-local-agree(Info;eo1;eo2;e1;e2) ∈ ℙ)

Lemma: local-class-output-agree
[Info,A:Type]. ∀[X:EClass(A)]. ∀[P:LocalClass(X)]. ∀[eo1,eo2:EO+(Info)]. ∀[e1:E]. ∀[e2:E].
  (X(e1) X(e2) ∈ bag(A)) supposing (eo-local-agree(Info;eo1;eo2;e1;e2) and (loc(e1) loc(e2) ∈ Id))

Lemma: local-class-output-agree2
[Info,A:Type]. ∀[X:EClass(A)].
  ∀[eo1,eo2:EO+(Info)]. ∀[e1:E]. ∀[e2:E].
    (X(e1) X(e2) ∈ bag(A)) supposing (eo-local-agree(Info;eo1;eo2;e1;e2) and (loc(e1) loc(e2) ∈ Id)) 
  supposing LocalClass(X)

Definition: global-class
GlobalClass(Info;A;X) ==
  ∃components:{bag(Id × hdataflow(Info;A))
  (X
  es,e. bag-union(bag-mapfilter(λp.(snd(snd(p)*(map(λx.info(x);before(e)))(info(e))));λp.fst(p) loc(e);
                                    components)))
  ∈ EClass(A))}

Lemma: global-class_wf
[Info,A:Type]. ∀[X:EClass(A)].  (GlobalClass(Info;A;X) ∈ ℙ')

Lemma: global-class-iff-bounded-local-class
[Info:Type]. ∀[A:{A:Type| valueall-type(A)} ]. ∀[X:EClass(A)].
  (GlobalClass(Info;A;X) ⇐⇒ LocalClass(X) ∧ LocBounded(A;X))

Definition: class-ap-val
X(v) ==  λes,e. bag-map(λf.(f v);X(e))

Lemma: class-ap-val_wf
[Info,A,B:Type]. ∀[X:EClass(A ⟶ B)]. ∀[a:A].  (X(a) ∈ EClass(B))

Lemma: class-ap-val-classrel
[Info,A,B:Type]. ∀[X:EClass(A ⟶ B)]. ∀[a:A]. ∀[b:B]. ∀[es:EO+(Info)]. ∀[e:E].
  uiff(b ∈ X(a)(e);↓∃f:A ⟶ B. ((b (f a) ∈ B) ∧ f ∈ X(e)))

Definition: eclass-union
eclass-union(X) ==  λes,e. bag-union(X(e))

Lemma: eclass-union_wf
[Info,A:Type]. ∀[X:EClass(bag(A))].  (eclass-union(X) ∈ EClass(A))

Lemma: eclass-union-classrel
[Info,A:Type]. ∀[X:EClass(bag(A))]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:A].
  uiff(v ∈ eclass-union(X)(e);↓∃b:bag(A). (v ↓∈ b ∧ b ∈ X(e)))

Definition: eclass0
(f X) ==  λes,e. ⋃x∈X(e).f loc(e) x

Lemma: eclass0_wf
[Info,B,C:Type]. ∀[X:EClass(B)]. ∀[f:Id ⟶ B ⟶ bag(C)].  ((f X) ∈ EClass(C))

Lemma: eclass0-classrel
[Info,B,C:Type]. ∀[X:EClass(B)]. ∀[f:Id ⟶ B ⟶ bag(C)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:C].
  uiff(v ∈ (f X)(e);↓∃b:B. (b ∈ X(e) ∧ v ↓∈ loc(e) b))

Lemma: eclass0-single-val
[Info,B,C:Type]. ∀[X:EClass(B)]. ∀[f:Id ⟶ B ⟶ bag(C)]. ∀[es:EO+(Info)].
  (single-valued-classrel(es;(f X);C)) supposing 
     (single-valued-classrel(es;X;B) and 
     (∀i:Id. ∀b:B.  single-valued-bag(f b;C)))

Lemma: eclass0-disjoint-classrel
[Info,A,B,C:Type]. ∀[Y:EClass(A)]. ∀[X:EClass(B)]. ∀[f:Id ⟶ B ⟶ bag(C)]. ∀[es:EO+(Info)].
  (disjoint-classrel(es;B;X;A;Y)  disjoint-classrel(es;C;(f X);A;Y))

Definition: eclass1
(f X) ==  λes,e. bag-map(f loc(e);X(e))

Lemma: eclass1_wf
[Info,B,C:Type]. ∀[X:EClass(B)]. ∀[f:Id ⟶ B ⟶ C].  ((f X) ∈ EClass(C))

Lemma: eclass1-classrel
[Info,B,C:Type]. ∀[f:Id ⟶ B ⟶ C]. ∀[X:EClass(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:C].
  uiff(v ∈ (f X)(e);↓∃b:B. (b ∈ X(e) ∧ (v (f loc(e) b) ∈ C)))

Lemma: eclass1-single-val
[Info,B,C:Type]. ∀[X:EClass(B)]. ∀[f:Id ⟶ B ⟶ C]. ∀[es:EO+(Info)].
  single-valued-classrel(es;(f X);C) supposing single-valued-classrel(es;X;B)

Lemma: eclass1-disjoint-classrel
[Info,A,B,C:Type]. ∀[Y:EClass(A)]. ∀[X:EClass(B)]. ∀[f:Id ⟶ B ⟶ C]. ∀[es:EO+(Info)].
  (disjoint-classrel(es;B;X;A;Y)  disjoint-classrel(es;C;(f X);A;Y))

Definition: eclass2
(X Y) ==  λes,e. ⋃f∈X(e).⋃b∈Y(e).f b

Lemma: eclass2_wf
[Info,B,C:Type]. ∀[X:EClass(B ⟶ bag(C))]. ∀[Y:EClass(B)].  ((X Y) ∈ EClass(C))

Lemma: eclass2-classrel
[Info,B,C:Type]. ∀[X:EClass(B ⟶ bag(C))]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:C].
  uiff(v ∈ (X Y)(e);↓∃f:B ⟶ bag(C). ∃b:B. (f ∈ X(e) ∧ b ∈ Y(e) ∧ v ↓∈ b))

Lemma: eclass2-eclass1-classrel
[Info,A,B,C:Type]. ∀[f:Id ⟶ A ⟶ B ⟶ bag(C)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:C].
  uiff(v ∈ ((f X) Y)(e);↓∃a:A. ∃b:B. (a ∈ X(e) ∧ b ∈ Y(e) ∧ v ↓∈ loc(e) b))

Lemma: eclass2-single-val
[Info,B,C:Type]. ∀[X:EClass(B ⟶ bag(C))]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)].
  (single-valued-classrel(es;(X Y);C)) supposing 
     (single-valued-classrel(es;X;B ⟶ bag(C)) and 
     single-valued-classrel(es;Y;B) and 
     (∀b:B. ∀cs:bag(C). ∀es:EO+(Info). ∀e:E.  (cs ∈ X(b)(e)  single-valued-bag(cs;C))))

Definition: eclass3
eclass3(X;Y) ==  λes,e. ⋃f∈X(e).bag-map(f;Y(e))

Lemma: eclass3_wf
[Info,B,C:Type]. ∀[X:EClass(B ⟶ C)]. ∀[Y:EClass(B)].  (eclass3(X;Y) ∈ EClass(C))

Lemma: eclass3-classrel
[Info,B,C:Type]. ∀[X:EClass(B ⟶ C)]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:C].
  uiff(v ∈ eclass3(X;Y)(e);↓∃f:B ⟶ C. ∃b:B. (f ∈ X(e) ∧ b ∈ Y(e) ∧ (v (f b) ∈ C)))

Lemma: eclass3-single-val
[Info,B,C:Type]. ∀[X:EClass(B ⟶ C)]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)].
  (single-valued-classrel(es;eclass3(X;Y);C)) supposing 
     (single-valued-classrel(es;X;B ⟶ C) and 
     single-valued-classrel(es;Y;B))

Lemma: eclass3-member
[Info,B,C:Type]. ∀[X:EClass(B ⟶ C)]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  uiff(↑e ∈b eclass3(X;Y);(↑e ∈b X) ∧ (↑e ∈b Y))

Lemma: eclass3-total
[Info,B,C:Type]. ∀[X:EClass(B ⟶ C)]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)].
  (es-total-class(es;eclass3(X;Y))) supposing (es-total-class(es;X) and es-total-class(es;Y))

Lemma: eclass3-functional
[Info,B,C:Type]. ∀[X:EClass(B ⟶ C)]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)].
  (eclass3(X;Y) is functional) supposing (X is functional and is functional)

Definition: eclass-cond
eclass-cond(X;Y) ==  λes,e. if e ∈b then eclass3(X;Y)(e) else Y(e) fi 

Lemma: eclass-cond_wf
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[Y:EClass(B)].  (eclass-cond(X;Y) ∈ EClass(B))

Lemma: eclass-cond-classrel
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:B].
  uiff(v ∈ eclass-cond(X;Y)(
           e);↓if e ∈b then ∃f:B ⟶ B. ∃b:B. (f ∈ X(e) ∧ b ∈ Y(e) ∧ (v (f b) ∈ B)) else v ∈ Y(e) fi )

Definition: eclass0-bag
eclass0-bag(f;X) ==  λes,e. (f loc(e) X(e))

Lemma: eclass0-bag_wf
[Info,B,C:Type]. ∀[X:EClass(B)]. ∀[f:Id ⟶ bag(B) ⟶ bag(C)].  (eclass0-bag(f;X) ∈ EClass(C))

Lemma: eclass0-bag-classrel
[Info,B,C:Type]. ∀[X:EClass(B)]. ∀[f:Id ⟶ bag(B) ⟶ bag(C)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:C].
  uiff(v ∈ eclass0-bag(f;X)(e);v ↓∈ loc(e) X(e))

Definition: eclass2-bag
eclass2-bag(X;Y) ==  λes,e. ⋃f∈X(e).f Y(e)

Lemma: eclass2-bag_wf
[Info,B,C:Type]. ∀[X:EClass(bag(B) ⟶ bag(C))]. ∀[Y:EClass(B)].  (eclass2-bag(X;Y) ∈ EClass(C))

Lemma: eclass2-bag-classrel
[Info,B,C:Type]. ∀[X:EClass(bag(B) ⟶ bag(C))]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:C].
  uiff(v ∈ eclass2-bag(X;Y)(e);↓∃f:bag(B) ⟶ bag(C). (f ∈ X(e) ∧ v ↓∈ Y(e)))

Definition: return-loc-class
return-loc-class(x) ==  λes,e. if first(e) then {x loc(e)} else {} fi 

Lemma: return-loc-class_wf
[Info,A:Type]. ∀[x:Id ⟶ A].  (return-loc-class(x) ∈ EClass(A))

Definition: return-loc-bag-class
return-loc-bag-class(x) ==  λes,e. if first(e) then loc(e) else {} fi 

Lemma: return-loc-bag-class_wf
[Info,A:Type]. ∀[x:Id ⟶ bag(A)].  (return-loc-bag-class(x) ∈ EClass(A))

Definition: simple-comb
simple-comb(F;Xs) ==  λes,e. (F k.(Xs es e)))

Lemma: simple-comb_wf
[Info,B:Type]. ∀[n:ℕ]. ∀[A:ℕn ⟶ Type]. ∀[Xs:k:ℕn ⟶ EClass(A k)]. ∀[F:(k:ℕn ⟶ bag(A k)) ⟶ bag(B)].
  (simple-comb(F;Xs) ∈ EClass(B))

Definition: simple-loc-comb
F|Loc; Xs| ==  λes,e. (F loc(e) k.(Xs es e)))

Lemma: simple-loc-comb_wf
[Info,B:Type]. ∀[n:ℕ]. ∀[A:ℕn ⟶ Type]. ∀[Xs:k:ℕn ⟶ EClass(A k)]. ∀[F:Id ⟶ (k:ℕn ⟶ bag(A k)) ⟶ bag(B)].
  (F|Loc; Xs| ∈ EClass(B))

Definition: simple-loc-comb0
λl.b[l]| ==  λl,w. b[l]|Loc; λx.[][x]|

Lemma: simple-loc-comb0_wf2
[Info,B:Type]. ∀[b:Id ⟶ bag(B)].  l.b[l]| | ∈ EClass(B))

Definition: in-eclass
e ∈b ==  (#(X eo e) =z 1)

Lemma: in-eclass_wf
[T:Type]. ∀[X:EClass(Top)]. ∀[eo:EO+(T)]. ∀[e:E].  (e ∈b X ∈ 𝔹)

Definition: eclass-val
X(e) ==  only(X eo e)

Lemma: eclass-val_wf
[T:Type]. ∀[A:es:EO+(T) ⟶ E ⟶ Type]. ∀[X:EClass(A[es;e])]. ∀[eo:EO+(T)]. ∀[e:E].  X(e) ∈ A[eo;e] supposing ↑e ∈b X

Lemma: single-eclass-val
[T:Type]. ∀[A:es:EO+(T) ⟶ E ⟶ Type]. ∀[X:EClass(A[es;e])]. ∀[eo:EO+(T)]. ∀[e:E].
  (X eo e) {X(e)} ∈ bag(A[eo;e]) supposing ↑e ∈b X

Definition: sv-class
Singlevalued(X) ==  ∀eo:EO+(Info). ∀e:E.  (#(X eo e) ≤ 1)

Lemma: sv-class_wf
[Info:Type]. ∀[A:es:EO+(Info) ⟶ E ⟶ Type]. ∀[X:EClass(A[es;e])].  (Singlevalued(X) ∈ ℙ')

Lemma: sv-class-iff
[Info:Type]. ∀[A:es:EO+(Info) ⟶ E ⟶ Type]. ∀[X:EClass(A[es;e])].
  (Singlevalued(X) ⇐⇒ ∀es:EO+(Info). ∀e:E.  ((X es e) if (#(X es e) =z 1) then es else {} fi  ∈ bag(A[es;e])))

Lemma: sv-classrel
[Info,A:Type]. ∀[X:EClass(A)].
  (Singlevalued(X)  (∀es:EO+(Info). ∀e:E. ∀v:A.  (v ∈ X(e) ⇐⇒ (↑e ∈b X) ∧ (v X(e) ∈ A))))

Definition: eclass-compose1
==  λeo,e. (f (X eo e))

Lemma: eclass-compose1_wf
[Info,A,B:Type]. ∀[f:bag(A) ⟶ bag(B)]. ∀[X:EClass(A)].  (f X ∈ EClass(B))

Definition: eclass-compose2
eclass-compose2(f;X;Y) ==  λeo,e. (f (X eo e) (Y eo e))

Lemma: eclass-compose2_wf
[Info,A,B,C:Type]. ∀[f:bag(A) ⟶ bag(B) ⟶ bag(C)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
  (eclass-compose2(f;X;Y) ∈ EClass(C))

Definition: eclass-compose3
eclass-compose3(f;X;Y;Z) ==  λeo,e. (f (X eo e) (Y eo e) (Z eo e))

Lemma: eclass-compose3_wf
[Info,A,B,C,D:Type]. ∀[f:bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(D)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)]. ∀[Z:EClass(C)].
  (eclass-compose3(f;X;Y;Z) ∈ EClass(D))

Definition: eclass-compose4
eclass-compose4(f;X;Y;Z;V) ==  λeo,e. (f (X eo e) (Y eo e) (Z eo e) (V eo e))

Lemma: eclass-compose4_wf
[Info,A,B,C,D,E:Type]. ∀[f:bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(D) ⟶ bag(E)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
[Z:EClass(C)]. ∀[V:EClass(D)].
  (eclass-compose4(f;X;Y;Z;V) ∈ EClass(E))

Lemma: eclass-compose1-derived
[f,X:Top].  (f eclass0-bag(λi.f;X))

Definition: es-empty-interface
Empty ==  λeo,x. {}

Lemma: es-empty-interface_wf
[Info,A:Type].  (Empty ∈ EClass(A))

Lemma: isempty_lemma
e,eo:Top.  (e ∈b Empty ff)

Definition: bind-class
X >x> Y[x] ==  λes,e. ⋃e'∈≤loc(e).⋃x∈es e'.Y[x] es.e' e

Lemma: bind-class_wf
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:A ⟶ EClass(B)].  (X >x> Y[x] ∈ EClass(B))

Definition: return-class
return-class(x) ==  λes,e. if first(e) then {x} else {} fi 

Lemma: return-class_wf
[Info,A:Type]. ∀[x:A].  (return-class(x) ∈ EClass(A))

Lemma: is-return-class
[Info:Type]. ∀[x:Top]. ∀[es:EO+(Info)]. ∀[e:E].  (e ∈b return-class(x) first(e))

Lemma: return-class-val
[Info:Type]. ∀[x:Top]. ∀[es:EO+(Info)]. ∀[e:E].  return-class(x)(e) supposing ↑e ∈b return-class(x)

Lemma: bind-return-right
[Info,T:Type]. ∀[X:EClass(T)].  (X >x> return-class(x) X ∈ EClass(T))

Lemma: bind-zero-right
[Info,T:Type]. ∀[X:EClass(T)].  (X >x> Empty Empty ∈ EClass(T))

Lemma: bind-return-left
[Info,T,S:Type]. ∀[x:T].  ∀f:T ⟶ EClass(S). (return-class(x) >z> f[z] f[x] ∈ EClass(S))

Lemma: bind-zero-left
[Info,T,S:Type].  ∀f:T ⟶ EClass(S). (Empty >z> f[z] Empty ∈ EClass(S))

Lemma: bind-class-assoc
[Info,T,S,U:Type]. ∀[X:EClass(T)]. ∀[Y:T ⟶ EClass(S)]. ∀[Z:S ⟶ EClass(U)].
  (X >x> Y[x] >y> Z[y] X >x> Y[x] >y> Z[y] ∈ EClass(U))

Definition: parallel-class
|| ==  eclass-compose2(λxs,ys. (xs ys);X;Y)

Lemma: parallel-class_wf
[T,Info:Type]. ∀[X,Y:EClass(T)].  (X || Y ∈ EClass(T))

Lemma: parallel-class-com
[T,Info:Type]. ∀[X,Y:EClass(T)].  (X || || X ∈ EClass(T))

Lemma: parallel-class-zero
[T,Info:Type]. ∀[X:EClass(T)].  (X || Empty X ∈ EClass(T))

Lemma: parallel-class-assoc
[T,Info:Type]. ∀[X,Y,Z:EClass(T)].  (X || || || || Z ∈ EClass(T))

Lemma: parallel-class-bind-left
[Info,T,S:Type]. ∀[X,Y:EClass(T)]. ∀[Z:T ⟶ EClass(S)].  (X || Y >t> Z[t] X >t> Z[t] || Y >t> Z[t] ∈ EClass(S))

Lemma: parallel-class-bind-right
[Info,T,S:Type]. ∀[X:EClass(T)]. ∀[Y,Z:T ⟶ EClass(S)].  (X >x> Y[x] || Z[x] X >x> Y[x] || X >x> Z[x] ∈ EClass(S))

Lemma: parallel-eclass2-left
[Info,B,C:Type]. ∀[X1,X2:EClass(B ⟶ bag(C))]. ∀[X:EClass(B)].  ((X1 X) || (X2 X) (X1 || X2 X) ∈ EClass(C))

Lemma: parallel-eclass2-right
[Info,B,C:Type]. ∀[X:EClass(B ⟶ bag(C))]. ∀[X1,X2:EClass(B)].  ((X X1) || (X X2) (X X1 || X2) ∈ EClass(C))

Definition: parallel-bag-class
The parallel composition of classes ⌜X[a]⌝ with parameter taken
from bag of parameters ⌜as⌝ can be defined using the bind class.
It has the expected class-rel. See: Error :parallel-bag-classrel

(In EventML, this is writtem  Output(\slf.as) >>)⋅

(||a∈as.X[a]) ==  return-loc-bag-class(λslf.as) >a> X[a]

Lemma: parallel-bag-class_wf
[B,Info,T:Type]. ∀[X:T ⟶ EClass(B)]. ∀[as:bag(T)].  ((||a∈as.X[a]) ∈ EClass(B))

Lemma: bind-class-rel
[Info,T,S:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)]. ∀[Y:T ⟶ EClass(S)]. ∀[e:E]. ∀[v:S].
  uiff(v ∈ X >u> Y[u](e);↓∃e':{e':E| e' ≤loc . ∃u:T. (u ∈ X(e') ∧ v ∈ Y[u](e)))

Lemma: bind-class-rel-weak
[Info,T,S:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T)]. ∀[Y:T ⟶ EClass(S)]. ∀[e:E]. ∀[v:S].
  (v ∈ X >u> Y[u](e) ⇐⇒ ↓∃e':{e':E| e' ≤loc . ∃u:T. (u ∈ X(e') ∧ v ∈ Y[u](e)))

Lemma: parallel-classrel
[T,Info:Type]. ∀[X,Y:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:T].  uiff(v ∈ || Y(e);v ∈ X(e) ↓∨ v ∈ Y(e))

Lemma: parallel-classrel-weak
[T,Info:Type]. ∀[X,Y:EClass(T)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:T].  (v ∈ || Y(e) ⇐⇒ v ∈ X(e) ↓∨ v ∈ Y(e))

Lemma: parallel-class-loc-bounded
[T,Info:Type]. ∀[X,Y:EClass(T)].  (LocBounded(T;X)  LocBounded(T;Y)  LocBounded(T;X || Y))

Definition: return-bag-class
return-bag-class(b) ==  λes,e. if first(e) then else {} fi 

Lemma: return-bag-class_wf
[Info,T:Type]. ∀[b:bag(T)].  (return-bag-class(b) ∈ EClass(T))

Lemma: parallel-as-bind
[A,Info:Type]. ∀[X,Y:EClass(A)].  (X || return-bag-class(tt.ff.{}) >b> if then else fi  ∈ EClass(A))

Lemma: simple-loc-comb-classrel
[Info,B:Type]. ∀[n:ℕ]. ∀[A:ℕn ⟶ Type]. ∀[Xs:k:ℕn ⟶ EClass(A k)]. ∀[f:Id ⟶ (k:ℕn ⟶ (A k)) ⟶ B]. ∀[F:Id
                                                                                                         ⟶ (k:ℕn
                                                                                                            ⟶ bag(A k))
                                                                                                         ⟶ bag(B)].
  ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:B].
    uiff(v ∈ F|Loc; Xs|(e);↓∃vs:k:ℕn ⟶ (A k). ((∀k:ℕn. vs[k] ∈ Xs[k](e)) ∧ (v (f loc(e) vs) ∈ B))) 
  supposing ∀x:Id. ∀v:B. ∀bs:k:ℕn ⟶ bag(A k).
              (v ↓∈ bs ⇐⇒ ↓∃vs:k:ℕn ⟶ (A k). ((∀k:ℕn. vs k ↓∈ bs k) ∧ (v (f vs) ∈ B)))

Lemma: es-interface-extensionality
[Info,A:Type]. ∀[X,Y:EClass(A)].
  (X Y ∈ EClass(A)) supposing 
     ((∀es:EO+(Info). ∀e:E.  ((↑e ∈b X)  (↑e ∈b Y)  (X(e) Y(e) ∈ A))) and 
     (∀es:EO+(Info). ∀e:E.  (↑e ∈b ⇐⇒ ↑e ∈b Y)) and 
     Singlevalued(X) and 
     Singlevalued(Y))

Definition: es-interface
Temporary AbsInterface(es;A) ==  E ⟶ (A Top)

Lemma: es-interface_wf
[Info,A:Type].  (EClass(A) ∈ 𝕌')

Definition: cond-class
[X?Y] ==  eclass-compose2(λbx,by. if (#(bx) =z 1) then bx else by fi ;X;Y)

Lemma: cond-class_wf
[Info,A:Type]. ∀[X,Y:EClass(A)].  ([X?Y] ∈ EClass(A))

Lemma: is-cond-class
[Info:Type]. ∀X,Y:EClass(Top). ∀es:EO+(Info). ∀e:E.  (↑e ∈b [X?Y] ⇐⇒ (↑e ∈b X) ∨ (↑e ∈b Y))

Lemma: cond-class-val
[Info,A:Type]. ∀[X,Y:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E].
  [X?Y](e) if e ∈b then X(e) else Y(e) fi  ∈ supposing ↑e ∈b [X?Y]

Lemma: es-interface-subtype_rel
[Info,A,B:Type].  EClass(A) ⊆EClass(B) supposing A ⊆B

Lemma: es-interface-subtype_rel2
[Info:Type]. ∀[A,B:es:EO+(Info) ⟶ E ⟶ Type].
  EClass(A[es;e]) ⊆EClass(B[es;e]) supposing ∀es:EO+(Info). ∀e:E.  (A[es;e] ⊆B[es;e])

Lemma: es-interface-top
[Info,A:Type]. ∀[X:EClass(A)].  (X ∈ EClass(Top))

Definition: es-interface-image
f'Ia ==  λb.bag-map(f;b) Ia

Lemma: es-interface-image_wf
[Info,A,B:Type]. ∀[f:A ⟶ B]. ∀[Ia:EClass(A)].  (f'Ia ∈ EClass(B))

Lemma: es-interface-image-derived
[f,X:Top].  (f'X loc.f X))

Definition: es-filter-image
f[X] ==  λb.if (#(b) =z 1) then only(b) else {} fi  X

Lemma: es-filter-image_wf
[Info,A,B:Type]. ∀[f:A ⟶ bag(B)]. ∀[X:EClass(A)].  (f[X] ∈ EClass(B))

Definition: es-interface-left
left(X) ==  λb.if (#(b) =z 1) then fst(bag-separate(b)) else {} fi  X

Lemma: es-interface-left_wf
[Info,A,B:Type]. ∀[X:EClass(A B)].  (left(X) ∈ EClass(A))

Definition: es-interface-right
right(X) ==  λb.if (#(b) =z 1) then snd(bag-separate(b)) else {} fi  X

Lemma: es-interface-right_wf
[Info,A,B:Type]. ∀[X:EClass(A B)].  (right(X) ∈ EClass(B))

Lemma: es-is-interface_wf_top
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].  (e ∈b X ∈ 𝔹)

Lemma: es-is-interface_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[e:E].  (e ∈b X ∈ 𝔹)

Definition: es-parameter-class
Parameter(p;X) ==  λes,e. if e ∈b then {p loc(e)} else {} fi 

Lemma: es-parameter-class_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[T:Type]. ∀[p:Id ⟶ T].  (Parameter(p;X) ∈ EClass(T))

Lemma: is-parameter-class
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[p:Top]. ∀[e:E].  (e ∈b Parameter(p;X) e ∈b X)

Definition: es-interface-empty
es-interface-empty(es;I) ==  ∀e:E. (¬↑e ∈b I)

Lemma: es-interface-empty_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)].  (es-interface-empty(es;X) ∈ ℙ)

Lemma: es-empty-interface-property
[Info:Type]. ∀[es:EO+(Info)].  es-interface-empty(es;Empty)

Definition: first-class
first-class(L) ==  reduce(λX,Y. [X?Y];Empty;L)

Lemma: first-class_wf
[Info,A:Type]. ∀[L:EClass(A) List].  (first-class(L) ∈ EClass(A))

Lemma: is-first-class
[Info,A:Type].  ∀L:EClass(A) List. ∀es:EO+(Info). ∀e:E.  (↑e ∈b first-class(L) ⇐⇒ (∃X∈L. ↑e ∈b X))

Lemma: is-first-class2
[Info,A:Type]. ∀[L:EClass(A) List]. ∀[es:EO+(Info)]. ∀[e:E].
  uiff(↑e ∈b first-class(L);0 < index-of-first in L.e ∈b X)

Lemma: first-class-val
[Info,A:Type]. ∀[L:EClass(A) List]. ∀[es:EO+(Info)]. ∀[e:E].
  (↑e ∈b L[index-of-first in L.e ∈b 1]) ∧ (first-class(L)(e) L[index-of-first in L.e ∈b 1](e) ∈ A) 
  supposing ↑e ∈b first-class(L)

Definition: es-interface-predicate
{I} ==  λe.(↑e ∈b I)

Lemma: es-interface-predicate_wf
[Info,A:Type]. ∀[X:EClass(A)]. ∀[es:EO+(Info)].  ({X} ∈ E ⟶ ℙ)

Lemma: es-interface-conditional-domain
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X,Y:EClass(A)]. ∀[e:E].  e ∈b [X?Y] e ∈b X ∨be ∈b Y

Lemma: es-interface-conditional-domain-iff
[Info:Type]. ∀es:EO+(Info). ∀[A:Type]. ∀X,Y:EClass(A). ∀e:E.  (↑e ∈b [X?Y] ⇐⇒ (↑e ∈b X) ∨ (↑e ∈b Y))

Lemma: is-interface-conditional
[Info:Type]. ∀es:EO+(Info). ∀X,Y:EClass(Top). ∀e:E.  (↑e ∈b [X?Y] ⇐⇒ (↑e ∈b X) ∨ (↑e ∈b Y))

Lemma: is-interface-conditional-implies
[Info:Type]. ∀es:EO+(Info). ∀X,Y:EClass(Top). ∀e:E.  (↑e ∈b X) ∨ (↑e ∈b Y) supposing ↑e ∈b [X?Y]

Lemma: es-interface-conditional-predicate-equivalent
[Info:Type]. ∀es:EO+(Info). ∀[A:Type]. ∀X,Y:EClass(A).  {[X?Y]} ⇐⇒ {X} ∨ {Y}

Lemma: es-interface-conditional-domain-member
[Info:Type]. ∀es:EO+(Info). ∀[A:Type]. ∀X,Y:EClass(A). ∀e:E.  (↑e ∈b [X?Y] ⇐⇒ (↑e ∈b X) ∨ (↑e ∈b Y))

Definition: es-E-interface
E(X) ==  {e:E| ↑e ∈b X} 

Lemma: es-E-interface_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)].  (E(X) ∈ Type)

Lemma: interface_predicate_set_lemma
X,es:Top.  ({e:E| {X} e}  E(X))

Lemma: es-E-interface-property
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E(X)].  (↑e ∈b X)

Lemma: cond-class-subtype1
[Info,A:Type]. ∀[X,Y:EClass(A)]. ∀[es:EO+(Info)].  (E(X) ⊆E([X?Y]))

Lemma: cond-class-subtype2
[Info,A:Type]. ∀[X,Y:EClass(A)]. ∀[es:EO+(Info)].  (E(Y) ⊆E([X?Y]))

Lemma: eclass-val_wf2
[Info:Type]. ∀[Z:EClass(Top)]. ∀[X:EClass(E(Z))]. ∀[eo:EO+(Info)]. ∀[e:E].  X(e) ∈ E(Z) supposing ↑e ∈b X

Definition: es-interface-vals
es-interface-vals(es; X; L) ==  map(λe.X(e);L)

Lemma: es-interface-vals_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[L:E(X) List].  (es-interface-vals(es; X; L) ∈ List)

Lemma: es-eq_wf-interface
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)].  (es-eq(es) ∈ EqDecider(E(X)))

Lemma: decidable__equal_es-E-interface
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀e,e':E(X).  Dec(e e' ∈ E(X))

Lemma: es-le-linorder-interface
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀j:Id.  Linorder({e':E(X)| loc(e') j ∈ Id} ;a,b.a ≤loc )

Definition: sys-antecedent
sys-antecedent(es;Sys) ==  {f:E(Sys) ⟶ E(Sys)| ∀x:E(Sys). c≤ x} 

Lemma: sys-antecedent_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[Sys:EClass(Top)].  (sys-antecedent(es;Sys) ∈ Type)

Lemma: es-fix_wf_antecedent
Info:Type. ∀es:EO+(Info). ∀X:EClass(Top). ∀f:sys-antecedent(es;X). ∀e:E(X).  (f**(e) ∈ E(X))

Definition: es-all-events
==  λeo,e. {⋅}

Lemma: es-all-events_wf
[Info:Type]. ∀[es:EO+(Info)].  (E ∈ EClass(Top))

Lemma: isallevents_lemma
e,eo:Top.  (e ∈b tt)

Lemma: E_interface_all_events_lemma
es:Top. (E(E) {e:E| True} )

Lemma: es-fix-fun-exp
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀f:sys-antecedent(es;X). ∀e:E(X).  (↓∃n:ℕ(f**(e) (f^n e) ∈ E(X)))

Definition: num-antecedents
#f(e) ==  fix((λnum-antecedents,e. if then else (num-antecedents (f e)) fi )) e

Lemma: num-antecedents_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[Sys:EClass(Top)]. ∀[f:sys-antecedent(es;Sys)]. ∀[e:E(Sys)].  (#f(e) ∈ ℕ)

Lemma: num-antecedents-property
[Info:Type]. ∀[es:EO+(Info)]. ∀[Sys:EClass(Top)]. ∀[f:sys-antecedent(es;Sys)]. ∀[e:E(Sys)].
  {((f (f^#f(e) e)) (f^#f(e) e) ∈ E(Sys)) ∧ (∀[i:ℕ#f(e)]. ((f (f^i e)) (f^i e) ∈ E(Sys))))}

Lemma: num-antecedents-fun_exp
[Info:Type]. ∀[es:EO+(Info)]. ∀[Sys:EClass(Top)]. ∀[f:sys-antecedent(es;Sys)]. ∀[n:ℕ]. ∀[e:E(Sys)].
  #f(f^n e) (#f(e) n) ∈ ℤ supposing n ≤ #f(e)

Lemma: sys-antecedent-fixedpoint
[Info:Type]
  ∀es:EO+(Info). ∀Sys:EClass(Top). ∀f:sys-antecedent(es;Sys). ∀e:E(Sys).
    ∃n:ℕ(((f (f^n e)) (f^n e) ∈ E(Sys)) ∧ ¬((f (f^n e)) (f^n e) ∈ E(Sys)) supposing 0 < n)

Lemma: sys-antecedent-closure
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀fs:sys-antecedent(es;X) List. ∀s:fset(E(X)).  ∃c:fset(E(X)). (c fs closure of s)

Definition: es-interface-sublist
es-interface-sublist(X;z) ==  filter(λe.e ∈b X;z)

Lemma: es-interface-sublist_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[z:E List].  (es-interface-sublist(X;z) ∈ E(X) List)

Lemma: es-E-interface-subtype
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)].  (E(X) ⊆ E)

Lemma: es-E-interface-subtype_rel
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)].  (E(X) ⊆E)

Lemma: es-E-interface-subtype_rel-implies
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y:EClass(Top)].  {∀[e:E(X)]. (↑e ∈b Y)} supposing E(X) ⊆E(Y)

Lemma: es-E-interface-strong-subtype
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)].  strong-subtype(E(X);E)

Lemma: es-E-interfaces-strong-subtype
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y:EClass(Top)].  uiff(E(X) ⊆E(Y);strong-subtype(E(X);E(Y)))

Lemma: es-E-interface_functionality-iff
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y:EClass(Top)].  uiff(E(X) ⊆E(Y);{∀[e:E]. ↑e ∈b supposing ↑e ∈b X})

Lemma: es-E-interface_functionality
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y:EClass(Top)].  E(X) ⊆E(Y) supposing ∀e:E. ((↑e ∈b X)  (↑e ∈b Y))

Lemma: es-E-interface-conditional
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y:EClass(Top)].  (E([X?Y]) ⊆{e:E| (↑e ∈b X) ∨ (↑e ∈b Y)} )

Lemma: es-E-interface-conditional2
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y:EClass(Top)].  (E([X?Y]) ⊆{e:E| (↑e ∈b Y) ∨ (↑e ∈b X)} )

Lemma: es-E-interface-conditional-subtype_rel
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y,Z:EClass(Top)].  (E([X?Y]) ⊆E(Z)) supposing ((E(Y) ⊆E(Z)) and (E(X) ⊆E(Z)))

Lemma: es-E-interface-conditional-subtype
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y,Z:EClass(Top)].  (E([X?Y]) ⊆ E(Z)) supposing ((E(Y) ⊆E(Z)) and (E(X) ⊆E(Z)))

Lemma: es-E-interface-conditional-subtype1
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y:EClass(Top)].  (E(X) ⊆E([X?Y]))

Lemma: es-E-interface-conditional-subtype2
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y:EClass(Top)].  (E(Y) ⊆E([X?Y]))

Lemma: es-causle-interface-retraction
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀f:E(X) ⟶ E(X).  ((∀x:E(X). c≤ x)  retraction(E(X);f))

Definition: interface-fifo
interface-fifo(es;X;f) ==  ∀e,e':E(X).  ((loc(e) loc(e') ∈ Id)  (f e <loc e')  (e <loc e'))

Lemma: interface-fifo_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E].  (interface-fifo(es;X;f) ∈ ℙ)

Definition: interface-order-preserving
interface-order-preserving(es;X;f) ==
  ∀e,e':E(X).  ((loc(e) loc(e') ∈ Id)  (loc(f e) loc(f e') ∈ Id)  ((f e <loc e') ⇐⇒ (e <loc e')))

Lemma: interface-order-preserving_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E].  (interface-order-preserving(es;X;f) ∈ ℙ)

Definition: strong-interface-fifo
strong-interface-fifo(es;X;f) ==  ∀e,e':E(X).  ((loc(e) loc(e') ∈ Id)  e ≤loc e'   e ≤loc e' )

Lemma: strong-interface-fifo_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E].  (strong-interface-fifo(es;X;f) ∈ ℙ)

Lemma: strong-interface-fifo-order-preserving
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀f:E(X) ⟶ E.  (strong-interface-fifo(es;X;f) ⇐⇒ interface-order-preserving(es;X;f))

Definition: global-order-preserving
global-order-preserving(es;X;f) ==
  ∀a,a':E(X).
    (a is f*(a')
     (∀b,b':E(X).
          (b is f*(b')  (loc(a) loc(b) ∈ Id)  (loc(a') loc(b') ∈ Id)  ((a <loc b) ⇐⇒ (a' <loc b')))))

Lemma: global-order-preserving_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)].  (global-order-preserving(es;X;f) ∈ ℙ)

Definition: convergent-flow
convergent-flow(es;X;f) ==
  (∀x,y:E(X).  ((¬((f x) x ∈ E(X)))  ((f y) y ∈ E(X)))  (loc(f x) loc(f y) ∈ Id)  (loc(x) loc(y) ∈ Id)))
  ∧ (∀x,y:E(X).  (x is f*(y)  (x y ∈ E))  (loc(x) loc(y) ∈ Id))))

Lemma: convergent-flow_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)].  (convergent-flow(es;X;f) ∈ ℙ')

Lemma: convergent-flow-order-preserving
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀f:E(X) ⟶ E(X).
    (interface-order-preserving(es;X;f)  global-order-preserving(es;X;f) supposing convergent-flow(es;X;f))

Definition: tree-flow
tree-flow{i:l}(es;X;f) ==
  (∀x,y:E(X).  ((¬((f x) x ∈ E(X)))  ((f y) y ∈ E(X)))  (loc(f x) loc(f y) ∈ Id)  (loc(x) loc(y) ∈ Id)))
  ∧ (∃R:Id ⟶ Id ⟶ ℙ
      (Trans(Id;i,j.R[i;j]) ∧ Irrefl(Id;i,j.R[i;j]) ∧ (∀x:E(X). ((¬((f x) x ∈ E))  R[loc(f x);loc(x)]))))

Lemma: tree-flow_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)].  (tree-flow{i:l}(es;X;f) ∈ ℙ')

Lemma: tree-flow-convergent
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)].
  convergent-flow(es;X;f) supposing tree-flow{i:l}(es;X;f)

Lemma: tree-flow-order-preserving
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀f:E(X) ⟶ E(X).
    (interface-order-preserving(es;X;f)  tree-flow{i:l}(es;X;f)  global-order-preserving(es;X;f))

Lemma: es-fix_wf2
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)].
  ∀[e:E(X)]. (f**(e) ∈ E(X)) supposing ∀x:E(X). c≤ x

Lemma: es-fix_property
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀f:E(X) ⟶ E(X).
    ((∀x:E(X). c≤ x)  (∀e:E(X). (((f f**(e)) f**(e) ∈ E(X)) ∧ f**(e) is f*(e))))

Lemma: es-fix-equal
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)].
  ∀[e:E(X)]. uiff(f**(e) e ∈ E;(f e) e ∈ E) supposing ∀x:E(X). c≤ x

Lemma: es-fix-step
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)].
  ∀[e:E(X)]. (f**(f e) f**(e) ∈ E(X)) supposing ∀x:E(X). c≤ x

Lemma: es-fix-connected
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)].
  ∀[e,a:E(X)].  f**(a) f**(e) ∈ E(X) supposing is f*(e) supposing ∀x:E(X). c≤ x

Lemma: es-fix-sqequal
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)]. ∀[e:E(X)].  f**(e) supposing (f e) e ∈ E

Lemma: es-fix-equal-E-interface
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)].
  ∀[e:E(X)]. uiff(f**(e) e ∈ E(X);(f e) e ∈ E) supposing ∀x:E(X). c≤ x

Lemma: es-fix-test
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)].
  ∀[e:E(X)]
    (((f f**(e)) f**(e) ∈ E(X))
    ∧ (f**(f e) f**(e) ∈ E(X))
    ∧ (∀[a:E(X)]. f**(a) f**(e) ∈ E(X) supposing is f*(e))) 
  supposing ∀x:E(X). c≤ x

Lemma: es-fix_property2
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀f:E(X) ⟶ E(X).  ((∀x:E(X). c≤ x)  (∀e:E(X). f**(e) is f*(f e)))

Lemma: es-fix-unique
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:E(X) ⟶ E(X)].
  ∀[a,e:E(X)].  (f**(e) a ∈ E(X)) supposing (((f a) a ∈ E) and is f*(e)) supposing ∀x:E(X). c≤ x

Lemma: fun-connected-relation
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀f:E(X) ⟶ E(X).
    ∀[R:E(X) ⟶ E(X) ⟶ ℙ]
      (Trans(E(X);e',e.R[e';e])
       Refl(E(X);e',e.R[e';e])
       (∀x:E(X). R[f x;x])
       (∀e',e:E(X).  (e' is f*(e)  R[e';e])))

Lemma: fun-connected-causle
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀f:E(X) ⟶ E(X).  ((∀x:E(X). c≤ x)  (∀e,e':E(X).  (e' is f*(e)  e' c≤ e)))

Lemma: loc-on-path-decomp
[Info:Type]
  ∀es:EO+(Info). ∀Sys:EClass(Top). ∀L:E(Sys) List. ∀j:Id.
    (loc-on-path(es;j;L)
     (∃u:E(Sys)
         ∃A,B:E(Sys) List. ((loc(u) j ∈ Id) ∧ (L (A [u B]) ∈ (E(Sys) List)) ∧ loc-on-path(es;j;A)))))

Lemma: es-fix-causle
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀f:E(X) ⟶ E(X).  ((∀x:E(X). c≤ x)  (∀e:E(X). f**(e) c≤ e))

Lemma: es-fix-causl
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀f:E(X) ⟶ E(X).
    ((∀x:E(X). c≤ x)  (∀e:E(X). (f**(e) < e) supposing ¬((f e) e ∈ E)))

Lemma: es-fix-order-preserving
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀f:E(X) ⟶ E(X).
    ((∀x:E(X). c≤ x)  global-order-preserving(es;X;f)  interface-order-preserving(es;X;λe.f**(e)))

Lemma: es-is-interface-image
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[f:Top]. ∀[Ia:EClass(A)]. ∀[e:E].  (e ∈b f'Ia e ∈b Ia)

Lemma: es-E-interface-image
[Info:Type]. ∀[es:EO+(Info)]. ∀[A,B:Type]. ∀[f:A ⟶ B]. ∀[Ia:EClass(A)].  ((E(f'Ia) ⊆E(Ia)) ∧ (E(Ia) ⊆E(f'Ia)))

Lemma: es-E-interface-predicate
[es,B,I:Top].  ({e:E| {I} e}  E(I))

Definition: es-interface-val
val(X,e) ==  λeo.do-apply(X eo;e)

Lemma: es-interface-val_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[e:E].  X(e) ∈ supposing ↑e ∈b X

Lemma: es-interface-implies-decidable
[Info:Type]
  ∀es:EO+(Info). ∀A:Type. ∀X:EClass(A).
    ∃P:E ⟶ A ⟶ ℙ((∀e:E. Dec(∃a:A. P[e;a])) ∧ (∀e:E. ((↑e ∈b ⇐⇒ ∃a:A. P[e;a]) ∧ P[e;X(e)] supposing ↑e ∈b X)))

Lemma: decidable-implies-es-interface
[Info,A:Type]. ∀[P:eo:EO+(Info) ⟶ E ⟶ A ⟶ ℙ].
  ((∀eo:EO+(Info). ∀e:E.  Dec(∃a:A. P[eo;e;a]))
   (∃X:EClass(A). ∀eo:EO+(Info). ∀e:E.  ((↑e ∈b ⇐⇒ ∃a:A. P[eo;e;a]) ∧ P[eo;e;X(e)] supposing ↑e ∈b X)))

Lemma: es-interface-val_wf2
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[e:E(X)].  (X(e) ∈ A)

Lemma: parameter-class-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[T:Type]. ∀[p:Id ⟶ T]. ∀[e:E].
  Parameter(p;X)(e) (p loc(e)) ∈ supposing ↑e ∈b Parameter(p;X)

Definition: es-interface-val?
X(e)?v ==  if e ∈b then X(e) else fi 

Lemma: es-interface-val?_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[e:E]. ∀[a:A].  (X(e)?a ∈ A)

Lemma: es-interface-set-subtype
[Info,A:Type]. ∀[P:A ⟶ ℙ]. ∀[X:EClass(A)].
  (X ∈ EClass({a:A| P[a]} )) supposing ((∀es:EO+(Info). ∀e:E(X).  P[X(e)]) and Singlevalued(X))

Definition: eclass-vals
X(L) ==  map(λe.X(e);L)

Lemma: eclass-vals_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[L:E(X) List].  (X(L) ∈ List)

Lemma: length-es-interface-vals
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[L:E(X) List].  (||X(L)|| ||L||)

Lemma: es-interface-vals-append
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[L1,L2:E(X) List].  (X(L1 L2) X(L1) X(L2))

Lemma: es-interface-vals-nil
[X,es:Top].  (X([]) [])

Lemma: es-interface-vals-singleton
[X,es,e:Top].  (X([e]) [X(e)])

Definition: es-prior-interface-vals
X(<e) ==  mapfilter(λe.X(e);λe.e ∈b X;before(e))

Lemma: es-prior-interface-vals_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[e:E].  (X(<e) ∈ List)

Definition: es-prior-interval-vals
X(e1, e2) ==  mapfilter(λe.X(e);λe.e ∈b X;(e1, e2))

Lemma: es-prior-interval-vals_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[e1,e2:E].  (X(e1, e2) ∈ List)

Definition: es-closed-interval-vals
X[e1;e2] ==  mapfilter(λe.X(e);λe.e ∈b X;[e1, e2])

Lemma: es-closed-interval-vals_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[e1,e2:E].  (X[e1;e2] ∈ List)

Lemma: es-closed-interval-vals-decomp
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[e1,e2:E].
  X[e1;e2]
  (if e1 <loc e2 ∧b e1 ∈b then [X(e1)] else [] fi  X(e1, e2) if e2 ∈b then [X(e2)] else [] fi )
  ∈ (A List) 
  supposing e1 ≤loc e2 

Lemma: es-interface-image-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[f:Top]. ∀[Ia:EClass(A)]. ∀[e:E].  f'Ia(e) Ia(e) supposing ↑e ∈b Ia

Lemma: es-interface-equality-recursion
[Info,A:Type]. ∀[X,Y:EClass(A)].
  Y ∈ EClass(A) 
  supposing ∀es:EO+(Info). ∀e:E.
              ((∀e':E. ((e' < e)  ((X es e') (Y es e') ∈ bag(A))))  ((X es e) (Y es e) ∈ bag(A)))

Lemma: es-interface-image-trivial
[Info,A:Type]. ∀[X:EClass(A)].  x.x'X X ∈ EClass(A))

Lemma: is-filter-image-sq
[Info:Type]. ∀[es:EO+(Info)]. ∀[f:Top]. ∀[X:EClass(Top)]. ∀[e:E].  (e ∈b f[X] e ∈b X ∧b (#(f X(e)) =z 1))

Lemma: assert-is-filter-image
[Info:Type]. ∀[es:EO+(Info)]. ∀[f:Top]. ∀[X:EClass(Top)]. ∀[e:E].
  (↑e ∈b f[X] if e ∈b then ↑(#(f X(e)) =z 1) else False fi )

Lemma: es-is-filter-image
[Info:Type]. ∀[es:EO+(Info)]. ∀[A,B:Type]. ∀[f:A ⟶ bag(B)]. ∀[X:EClass(A)]. ∀[e:E].
  uiff(↑e ∈b f[X];(↑e ∈b X) ∧ (#(f X(e)) 1 ∈ ℤ))

Lemma: es-is-filter-image2
[Info:Type]. ∀[es:EO+(Info)]. ∀[A,B:Type]. ∀[f:A ⟶ bag(B)]. ∀[X:EClass(A)]. ∀[e:E].
  uiff(↑e ∈b f[X];{(↑e ∈b X) ∧ (#(f X(e)) 1 ∈ ℤ)})

Lemma: es-filter-image-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[f:Top]. ∀[X:EClass(Top)]. ∀[e:E].  f[X](e) only(f X(e)) supposing ↑e ∈b X

Lemma: es-filter-image-val2
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[f:A ⟶ bag(Top)]. ∀[X:EClass(A)]. ∀[e:E].
  f[X](e) only(f X(e)) supposing ↑e ∈b f[X]

Lemma: es-E-filter-image
[Info,A:Type]. ∀[f:A ⟶ bag(Top)]. ∀[es:EO+(Info)]. ∀[X:EClass(A)].  (E(f[X]) ⊆E(X))

Definition: mapfilter-class
(f[v] where from such that P[v]) ==  λv.if P[v] then {f[v]} else {} fi [X]

Lemma: mapfilter-class_wf
[Info,A,B:Type]. ∀[P:A ⟶ 𝔹]. ∀[f:A ⟶ B]. ∀[X:EClass(A)].  ((f[v] where from such that P[v]) ∈ EClass(B))

Lemma: is-mapfilter-class
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[P:A ⟶ 𝔹]. ∀[f:Top]. ∀[X:EClass(A)]. ∀[e:E].
  uiff(↑e ∈b (f[v] where from such that P[v]);(↑e ∈b X) ∧ (↑P[X(e)]))

Lemma: mapfilter-class-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[A,B:Type]. ∀[P:A ⟶ 𝔹]. ∀[f:A ⟶ B]. ∀[X:EClass(A)]. ∀[e:E].
  (f[v] where from such that P[v])(e) f[X(e)] supposing ↑e ∈b (f[v] where from such that P[v])

Lemma: mapfilter-class_functionality
[Info,A1,A2,B:Type]. ∀[P1:A1 ⟶ 𝔹]. ∀[P2:A2 ⟶ 𝔹]. ∀[f1:A1 ⟶ B]. ∀[f2:A2 ⟶ B]. ∀[X1:EClass(A1)]. ∀[X2:EClass(A2)].
  (f1[v] where from X1 such that P1[v]) (f2[v] where from X2 such that P2[v]) ∈ EClass(B) 
  supposing ∀es:EO+(Info). ∀e:E.
              ((↑e ∈b X1 ⇐⇒ ↑e ∈b X2)
              ∧ ((↑e ∈b X1)
                 (↑e ∈b X2)
                 ((↑P1[X1(e)] ⇐⇒ ↑P2[X2(e)]) ∧ ((↑P1[X1(e)])  (↑P2[X2(e)])  (f1[X1(e)] f2[X2(e)] ∈ B)))))

Definition: map-class
(f[v] where from X) ==  λv.{f[v]}[X]

Lemma: map-class_wf
[Info,A,B:Type]. ∀[f:A ⟶ B]. ∀[X:EClass(A)].  ((f[v] where from X) ∈ EClass(B))

Lemma: is-map-class
[Info:Type]. ∀[es:EO+(Info)]. ∀[f:Top]. ∀[X:EClass(Top)]. ∀[e:E].  (e ∈b (f[v] where from X) e ∈b X)

Lemma: E-map-class
[Info:Type]. ∀[es:EO+(Info)]. ∀[f:Top]. ∀[X:EClass(Top)].  (E((f[v] where from X)) E(X) ∈ Type)

Lemma: map-class-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[f:Top]. ∀[X:EClass(Top)]. ∀[e:E].
  (f[v] where from X)(e) f[X(e)] supposing ↑e ∈b (f[v] where from X)

Lemma: map-class_functionality
[Info,T,A,B:Type]. ∀[f:A ⟶ T]. ∀[g:B ⟶ T]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
  (f[a] where from X) (g[b] where from Y) ∈ EClass(T) 
  supposing ∀es:EO+(Info). ∀e:E.  ((↑e ∈b ⇐⇒ ↑e ∈b Y) ∧ ((↑e ∈b X)  (↑e ∈b Y)  (f[X(e)] g[Y(e)] ∈ T)))

Lemma: filter-image_functionality
[Info,T,A,B:Type]. ∀[f:A ⟶ bag(T)]. ∀[g:B ⟶ bag(T)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
  f[X] g[Y] ∈ EClass(T) 
  supposing ∀es:EO+(Info). ∀e:E.  ((↑e ∈b ⇐⇒ ↑e ∈b Y) ∧ ((↑e ∈b X)  (↑e ∈b Y)  ((f X(e)) (g Y(e)) ∈ bag(T))))

Definition: es-tagged-true-class
Tagged_tt(X) ==  λp.if snd(p) then {fst(p)} else {} fi [X]

Lemma: es-tagged-true-class_wf
[Info,T:Type]. ∀[X:EClass(T × 𝔹)].  (Tagged_tt(X) ∈ EClass(T))

Lemma: is-tagged-true
[Info:Type]. ∀[es:EO+(Info)]. ∀[T:Type]. ∀[X:EClass(T × 𝔹)]. ∀[e:E].
  uiff(↑e ∈b Tagged_tt(X);(↑e ∈b X) ∧ (↑(snd(X(e)))))

Lemma: tagged-true-subtype
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top × 𝔹)].  (E(Tagged_tt(X)) ⊆E(X))

Lemma: tagged-true-property
[Info,T:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(T × 𝔹)]. ∀[e:E(Tagged_tt(X))].  ((↑e ∈b X) ∧ (↑(snd(X(e)))))

Lemma: tagged-true-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[T:Type]. ∀[X:EClass(T × 𝔹)]. ∀[e:E].
  Tagged_tt(X)(e) fst(X(e)) supposing ↑e ∈b Tagged_tt(X)

Definition: es-interface-map
es-interface-map(f;X) ==  λes,e. let es in if (#(b) =z 1) then only(b) else {} fi 

Lemma: es-interface-map_wf
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[f:⋂es:EO+(Info). (A ⟶ E(X) ⟶ bag(B))].  (es-interface-map(f;X) ∈ EClass(B))

Lemma: es-is-interface-map
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[f:Top]. ∀[e:E].
  (e ∈b es-interface-map(f;X) e ∈b X ∧b (#(f X(e) e) =z 1))

Lemma: es-interface-map-val
[Info,A:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(A)]. ∀[f:A ⟶ E(X) ⟶ bag(Top)]. ∀[e:E].
  es-interface-map(f;X)(e) only(f X(e) e) supposing ↑e ∈b es-interface-map(f;X)

Lemma: es-interface-val-conditional
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X,Y:EClass(A)]. ∀[e:E].
  [X?Y](e) if e ∈b then X(e) else Y(e) fi  ∈ supposing ↑e ∈b [X?Y]

Definition: first-eclass
first-eclass(Xs) ==
  λeo,e. accumulate (with value and list item X):
          if (#(b) =z 1) then else eo fi 
         over list:
           Xs
         with starting value:
          {})

Lemma: first-eclass_wf
[Info,A:Type]. ∀[Xs:EClass(A) List].  (first-eclass(Xs) ∈ EClass(A))

Lemma: in-first-eclass
[Info,A:Type].  ∀Xs:EClass(A) List. ∀es:EO+(Info). ∀e:E.  (↑e ∈b first-eclass(Xs) ⇐⇒ (∃X∈Xs. ↑e ∈b X))

Lemma: first-eclass-val
[Info,A:Type].
  ∀Xs:EClass(A) List. ∀es:EO+(Info). ∀e:E.
    (∃X∈Xs. (↑e ∈b X) ∧ (first-eclass(Xs)(e) X(e) ∈ A)) supposing ↑e ∈b first-eclass(Xs)

Lemma: is-interface-left
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top Top)]. ∀[e:E].  uiff(↑e ∈b left(X);(↑e ∈b X) ∧ (↑isl(X(e))))

Lemma: is-interface-right
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top Top)]. ∀[e:E].  uiff(↑e ∈b right(X);(↑e ∈b X) ∧ (¬↑isl(X(e))))

Definition: es-interface-union
X+Y ==  eclass-compose2(λxs,ys. if (#(xs) =z 1) then {inl only(xs)} if (#(ys) =z 1) then {inr only(ys) else {} fi ;X;Y\000C)

Lemma: es-interface-union_wf
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].  (X+Y ∈ EClass(A B))

Lemma: es-is-interface-union
[Info:Type]. ∀es:EO+(Info). ∀[A,B:Type].  ∀X:EClass(A). ∀Y:EClass(B). ∀e:E.  (↑e ∈b X+Y ⇐⇒ (↑e ∈b X) ∨ (↑e ∈b Y))

Lemma: interface-union-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)]. ∀[e:E].
  X+Y(e) if e ∈b then inl X(e) else inr Y(e)  fi  ∈ (A B) supposing ↑e ∈b X+Y

Lemma: es-interface-union-left
[Info,A:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(Top)].  left(X+Y) X ∈ EClass(A) supposing Singlevalued(X)

Definition: inl-class
inl-class(X) ==  λb.bag-map(λx.(inl x);b) X

Lemma: inl-class_wf
[Info,A:Type]. ∀[X:EClass(A)].  (inl-class(X) ∈ EClass(A Void))

Definition: outl-class
outl-class(X) ==  λb.bag-mapfilter(λx.outl(x);λx.isl(x);b) X

Lemma: outl-class_wf
[Info,A:Type]. ∀[X:EClass(A Top)].  (outl-class(X) ∈ EClass(A))

Definition: inr-class
inr-class(X) ==  λb.bag-map(λx.(inr );b) X

Lemma: inr-class_wf
[Info,A:Type]. ∀[X:EClass(A)].  (inr-class(X) ∈ EClass(Void A))

Definition: outr-class
outr-class(X) ==  λb.bag-mapfilter(λx.outr(x);λx.(¬bisl(x));b) X

Lemma: outr-class_wf
[Info,A:Type]. ∀[X:EClass(Top A)].  (outr-class(X) ∈ EClass(A))

Definition: or-class
or-class(X;Y) ==  inl-class(X) || inr-class(Y)

Lemma: or-class_wf
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].  (or-class(X;Y) ∈ EClass(A B))

Lemma: outl-or-class
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].  (outl-class(or-class(X;Y)) X ∈ EClass(A))

Lemma: outr-or-class
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].  (outr-class(or-class(X;Y)) Y ∈ EClass(B))

Definition: es-interface-or
(X Y) ==  eclass-compose2(λxs,ys. oob-apply(xs;ys);X;Y)

Lemma: es-interface-or_wf
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].  ((X Y) ∈ EClass(one_or_both(A;B)))

Lemma: is-interface-or
[Info:Type]. ∀es:EO+(Info). ∀X,Y:EClass(Top). ∀e:E.  (↑e ∈b (X Y) ⇐⇒ (↑e ∈b X) ∨ (↑e ∈b Y))

Lemma: interface-or-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)]. ∀[e:E].
  (X Y)(e)
  if e ∈b then if e ∈b then oobboth(<X(e), Y(e)>else oobleft(X(e)) fi  else oobright(Y(e)) fi 
  ∈ one_or_both(A;B) 
  supposing ↑e ∈b (X Y)

Definition: es-interface-or-left
es-interface-or-left(X) ==  λx.oob-getleft?(x)[X]

Lemma: es-interface-or-left_wf
[Info,A,B:Type]. ∀[X:EClass(one_or_both(A;B))].  (es-interface-or-left(X) ∈ EClass(A))

Lemma: es-interface-or-left-property
[Info,A:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(Top)].
  es-interface-or-left((X Y)) X ∈ EClass(A) supposing Singlevalued(X)

Definition: es-interface-or-right
es-interface-or-right(X) ==  λx.oob-getright?(x)[X]

Lemma: es-interface-or-right_wf
[Info,A,B:Type]. ∀[X:EClass(one_or_both(A;B))].  (es-interface-or-right(X) ∈ EClass(B))

Lemma: es-interface-or-right-property
[Info,A:Type]. ∀[X:EClass(Top)]. ∀[Y:EClass(A)].
  es-interface-or-right((X Y)) Y ∈ EClass(A) supposing Singlevalued(Y)

Lemma: es-interface-or-hasright
[Info:Type]. ∀[es:EO+(Info)]. ∀[A,B:EClass(Top)]. ∀[e:E].  oob-hasright((A B)(e)) e ∈b supposing ↑e ∈b (A B)

Lemma: es-interface-or-hasleft
[Info:Type]. ∀[es:EO+(Info)]. ∀[A,B:EClass(Top)]. ∀[e:E].  oob-hasleft((A B)(e)) e ∈b supposing ↑e ∈b (A B)

Lemma: es-interface-or-getleft
[Info:Type]. ∀[es:EO+(Info)]. ∀[A,B:EClass(Top)]. ∀[e:E].  oob-getleft((A B)(e)) A(e) supposing ↑e ∈b A

Lemma: es-interface-or-getright
[Info:Type]. ∀[es:EO+(Info)]. ∀[A,B:EClass(Top)]. ∀[e:E].  oob-getright((A B)(e)) B(e) supposing ↑e ∈b B

Definition: es-interface-state
es-interface-state(X; g) ==  λes,e. (g X(filter(λe.e ∈b X;≤loc(e))))

Lemma: es-interface-state_wf
[Info,T,A:Type]. ∀[X:EClass(T)]. ∀[g:(T List) ⟶ bag(A)].  (es-interface-state(X; g) ∈ EClass(A))

Definition: es-interface-restrict
(I|p) ==  λeo,e. case eo of inl(x) => eo inr(x) => {}

Lemma: es-interface-restrict_wf
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])].
  ((I|p) ∈ EClass(A))

Definition: es-interface-co-restrict
(I|¬p) ==  λeo,e. case eo of inl(x) => {} inr(x) => eo e

Lemma: es-interface-co-restrict_wf
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])].
  ((I|¬p) ∈ EClass(A))

Lemma: es-is-interface-restrict
[Info,A:Type].
  ∀I:EClass(A)
    ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]
      ∀p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e]). ∀es:EO+(Info). ∀e:E.  (↑e ∈b (I|p) ⇐⇒ (↑e ∈b I) ∧ P[es;e])

Lemma: es-is-interface-restrict-guard
[Info,A:Type].
  ∀I:EClass(A)
    ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]
      ∀p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e]). ∀es:EO+(Info). ∀e:E.  (↑e ∈b (I|p) ⇐⇒ {(↑e ∈b I) ∧ P[es;e]})

Lemma: es-is-interface-restrict2
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])]. ∀[es:EO+(Info)].
[e:E].
  ↑e ∈b supposing ↑e ∈b (I|p)

Lemma: es-is-interface-co-restrict
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])]. ∀[es:EO+(Info)].
[e:E].
  uiff(↑e ∈b (I|¬p);(↑e ∈b I) ∧ P[es;e]))

Lemma: es-interface-val-restrict
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])]. ∀[es:EO+(Info)].
[e:E].
  (I|p)(e) I(e) ∈ supposing ↑e ∈b (I|p)

Lemma: es-interface-val-restrict-sq
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])]. ∀[es:EO+(Info)].
[e:E].
  (I|p)(e) I(e) supposing ↑e ∈b (I|p)

Lemma: es-interface-val-co-restrict
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])]. ∀[es:EO+(Info)].
[e:E].
  (I|¬p)(e) I(e) ∈ supposing ↑e ∈b (I|¬p)

Lemma: es-interface-restrict-trivial
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])].
  (I|p) I ∈ EClass(A) supposing ∀es:EO+(Info). ∀e:E.  ((¬P[es;e])  ((I es e) {} ∈ bag(A)))

Lemma: es-interface-restrict-idempotent
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])].
  (((I|p)|p) (I|p) ∈ EClass(A))

Lemma: es-E-interface-restrict
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])]. ∀[es:EO+(Info)].
  (E((I|p)) ⊆E(I))

Lemma: es-E-interface-co-restrict
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])]. ∀[es:EO+(Info)].
  (E((I|¬p)) ⊆E(I))

Definition: es-interface-disjoint
X ⋂ ==  ∀es:EO+(Info). ∀e:E.  ((↑e ∈b X) ∧ (↑e ∈b Y)))

Lemma: es-interface-disjoint_wf
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].  (X ⋂ 0 ∈ ℙ')

Lemma: es-interface-val-disjoint
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[Xs:EClass(A) List].
  ∀[X:EClass(A)]. ∀[e:E]. first-eclass(Xs)(e) X(e) ∈ supposing ↑e ∈b supposing (X ∈ Xs) 
  supposing (∀X∈Xs.(∀Y∈Xs.(X Y ∈ EClass(A)) ∨ X ⋂ 0))

Lemma: es-interface-restrict-disjoint
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])].
  (I|p) ⋂ (I|¬p) 0

Lemma: es-interface-restrict-conditional
[Info,A:Type]. ∀[I:EClass(A)]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ]. ∀[p:∀es:EO+(Info). ∀e:E.  Dec(P[es;e])].
  [(I|p)?(I|¬p)] I ∈ EClass(A) supposing Singlevalued(I)

Definition: es-interface-filter
X|a.P[a] ==  λb.if (#(b) =z 1) then [a∈b|P[a]] else {} fi  X

Lemma: es-interface-filter_wf
[Info,A:Type]. ∀[X:EClass(A)]. ∀[P:A ⟶ 𝔹].  (X|a.P[a] ∈ EClass({a:A| ↑P[a]} ))

Lemma: es-is-interface-filter
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[P:A ⟶ 𝔹]. ∀[e:E].
  uiff(↑e ∈b X|a.P[a];{(↑e ∈b X) ∧ (↑P[X(e)])})

Lemma: es-interface-filter-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A)]. ∀[P:A ⟶ 𝔹]. ∀[e:E].
  X|a.P[a](e) X(e) supposing ↑e ∈b X|a.P[a]

Definition: class-at
X@locs ==  λes,e. if bag-deq-member(IdDeq;loc(e);locs) then es else {} fi 

Lemma: class-at_wf
[Info,T:Type]. ∀[X:EClass(T)]. ∀[locs:bag(Id)].  (X@locs ∈ EClass(T))

Lemma: classrel-at
[Info,T:Type]. ∀[X:EClass(T)]. ∀[locs:bag(Id)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:T].
  (v ∈ X@locs(e) ⇐⇒ loc(e) ↓∈ locs ∧ v ∈ X(e))

Lemma: class-at-loc-bounded
[Info,T:Type]. ∀[X:EClass(T)].  ∀locs:bag(Id). LocBounded(T;X@locs)

Definition: es-interface-at
X@i ==  λes,e. if loc(e) then es else {} fi 

Lemma: es-interface-at_wf
[Info,T:Type]. ∀[X:EClass(T)]. ∀[i:Id].  (X@i ∈ EClass(T))

Lemma: is-interface-at
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[i:Id]. ∀[e:E].  uiff(↑e ∈b X@i;(loc(e) i ∈ Id) ∧ (↑e ∈b X))

Lemma: interface-at-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[T:Type]. ∀[X:EClass(T)]. ∀[i:Id]. ∀[e:E].  X@i(e) X(e) supposing ↑e ∈b X@i

Lemma: member-interface-at
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E(X)].  (e ∈ E(X@loc(e)))

Lemma: interface-at-subtype
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[i:Id].  (E(X@i) ⊆E(X))

Definition: es-interface-part
(X|g=i) ==  λeo,e. let eo in if (#(b) =z 1) then if then else {} fi  else {} fi 

Lemma: es-interface-part_wf
[Info,T:Type]. ∀[X:EClass(T)]. ∀[g:⋂es:EO+(Info). (E(X) ⟶ Id)]. ∀[i:Id].  ((X|g=i) ∈ EClass(T))

Lemma: is-interface-part
[Info:Type]. ∀[es:EO+(Info)]. ∀[T:Type]. ∀[X:EClass(T)]. ∀[g:E(X) ⟶ Id]. ∀[i:Id]. ∀[e:E].
  uiff(↑e ∈b (X|g=i);(↑e ∈b X) ∧ ((g e) i ∈ Id))

Lemma: es-is-interface-p-first
[Info:Type]. ∀es:EO+(Info). ∀[A:Type]. ∀Ias:EClass(A) List. ∀e:E.  (↑e ∈b first-eclass(Ias) ⇐⇒ (∃I∈Ias. ↑e ∈b I))

Lemma: es-E-interface-first
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[Ias:EClass(A) List]. ∀[i:ℕ||Ias||].  (E(Ias[i]) ⊆E(first-eclass(Ias)))

Lemma: es-E-interface-first-class
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[Ias:EClass(A) List]. ∀[i:ℕ||Ias||].  (E(Ias[i]) ⊆E(first-class(Ias)))

Lemma: es-E-empty-interface
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)].  (E(Empty) ⊆E(X))

Definition: es-interface-history
es-interface-history(es;X;e) ==  concat(mapfilter(λe.X(e);λe.e ∈b X;≤loc(e)))

Lemma: es-interface-history_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A List)]. ∀[e:E].  (es-interface-history(es;X;e) ∈ List)

Lemma: es-interface-history-first
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A List)]. ∀[e:E].
  es-interface-history(es;X;e) if e ∈b then X(e) else [] fi  ∈ (A List) supposing ↑first(e)

Lemma: es-interface-history-pred
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[X:EClass(A List)]. ∀[e:E].
  es-interface-history(es;X;e)
  if e ∈b then es-interface-history(es;X;pred(e)) X(e) else es-interface-history(es;X;pred(e)) fi 
  ∈ (A List) 
  supposing ¬↑first(e)

Lemma: es-interface-history-iseg
[Info:Type]
  ∀es:EO+(Info)
    ∀[A:Type]. ∀X:EClass(A List). ∀e',e:E.  (e ≤loc e'   es-interface-history(es;X;e) ≤ es-interface-history(es;X;e'))

Lemma: member-es-interface-history
[Info:Type]
  ∀es:EO+(Info)
    ∀[A:Type]
      ∀X:EClass(A List). ∀e:E. ∀a:A.
        ((a ∈ es-interface-history(es;X;e)) ⇐⇒ ∃e':E. (((↑e' ∈b X) ∧ e' ≤loc ) ∧ (a ∈ X(e'))))

Definition: eclass-events
eclass-events(es;X;L) ==  filter(λe.e ∈b X;L)

Lemma: eclass-events_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[L:E List].  (eclass-events(es;X;L) ∈ E(X) List)

Lemma: member-es-interface-events
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀L:E List. ∀e:E(X).  ((e ∈ eclass-events(es;X;L)) ⇐⇒ (e ∈ L))

Lemma: member-es-interface-events2
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀L:E List. ∀e:E.  ((e ∈ eclass-events(es;X;L)) ⇐⇒ {(↑e ∈b X) ∧ (e ∈ L)})

Lemma: es-interface-events-append
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[L1,L2:E List].
  (eclass-events(es;X;L1 L2) eclass-events(es;X;L1) eclass-events(es;X;L2))

Definition: es-interface-predecessors
(X)(e) ==  eclass-events(es;X;≤loc(e))

Lemma: es-interface-predecessors_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].  (≤(X)(e) ∈ {a:E(X)| loc(a) loc(e) ∈ Id}  List)

Lemma: es-interface-predecessors-cases
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].
  (≤(X)(e) if e ∈b then if first(e) then [e] else ≤(X)(pred(e)) [e] fi 
  if first(e) then []
  else ≤(X)(pred(e))
  fi )

Lemma: es-interface-predecessors-member
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E(X).  (e ∈ ≤(X)(e))

Lemma: es-interface-predecessors-member2
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E(X).  (e ∈ ≤(X)(e))

Lemma: es-interface-predecessors-nonempty
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E(X)].  0 < ||≤(X)(e)||

Lemma: es-interface-predecessors-nonnull
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E(X)].  (null(≤(X)(e)) ff)

Lemma: interface-predecessors-all-events
[Info:Type]. ∀[es:EO+(Info)]. ∀[e:E].  (≤(E)(e) ~ ≤loc(e))

Definition: es-interface-prior-vals
X(≤e) ==
  fix((λes-interface-prior-vals,e. (if e ∈b then [X(e)] else [] fi 
                                  if first(e) then [] else es-interface-prior-vals pred(e) fi ))) 
  e

Lemma: es-interface-prior-vals_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[T:Type]. ∀[X:EClass(T)]. ∀[e:E].  (X(≤e) ∈ List)

Lemma: prior-vals-non-null
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E(X)].  (¬↑null(X(≤e)))

Definition: es-interface-count
#X ==  λes,e. if e ∈b then {||≤(X)(e)||} else {} fi 

Lemma: es-interface-count_wf
[Info:Type]. ∀[X:EClass(Top)].  (#X ∈ EClass(ℕ))

Lemma: is-interface-count
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].  (e ∈b #X e ∈b X)

Lemma: es-interface-count-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].  #X(e) ||≤(X)(e)|| supposing ↑e ∈b X

Definition: es-interface-accum
es-interface-accum(f;x;X) ==
  λes,e. if e ∈b X
        then {accumulate (with value and list item e):
               X(e)
              over list:
                ≤(X)(e)
              with starting value:
               x)}
        else {}
        fi 

Lemma: es-interface-accum_wf
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[b:B]. ∀[f:B ⟶ A ⟶ B].  (es-interface-accum(f;b;X) ∈ EClass(B))

Lemma: is-interface-accum
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[b,f:Top]. ∀[e:E].  (e ∈b es-interface-accum(f;b;X) e ∈b X)

Lemma: es-interface-accum-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[b,f:Top]. ∀[e:E].
  es-interface-accum(f;b;X)(e) accumulate (with value and list item e):
                                  X(e)
                                 over list:
                                   ≤(X)(e)
                                 with starting value:
                                  b) 
  supposing ↑e ∈b es-interface-accum(f;b;X)

Definition: imax-class
(maximum f[v] ≥ lb with from X) ==  es-interface-accum(λmx,v. imax(mx;f[v]);lb;X)

Lemma: imax-class_wf
[Info,T:Type]. ∀[f:T ⟶ ℤ]. ∀[lb:ℤ]. ∀[X:EClass(T)].  ((maximum f[v] ≥ lb with from X) ∈ EClass(ℤ))

Lemma: is-imax-class
[Info:Type]. ∀[es:EO+(Info)]. ∀[f,lb:Top]. ∀[X:EClass(Top)]. ∀[e:E].  (e ∈b (maximum f[v] ≥ lb with from X) e ∈b X)

Lemma: E-imax-class
[Info:Type]. ∀[es:EO+(Info)]. ∀[f,lb:Top]. ∀[X:EClass(Top)].  (E((maximum f[v] ≥ lb with from X)) E(X) ∈ Type)

Lemma: imax-class-val
[Info,T:Type]. ∀[f:T ⟶ ℤ]. ∀[es:EO+(Info)]. ∀[lb:ℤ]. ∀[X:EClass(T)]. ∀[e:E(X)].
  ((maximum f[v] ≥ lb with from X)(e) imax-list([lb map(λv.f[v];X(≤(X)(e)))]) ∈ ℤ)

Definition: accum-class
accum-class(a,x.f[a; x];x.base[x];X) ==
  λes,e. if e ∈b then {accum_list(a,e.f[a; X(e)];e.base[X(e)];≤(X)(e))} else {} fi 

Lemma: accum-class_wf
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[b:A ⟶ B]. ∀[f:B ⟶ A ⟶ B].  (accum-class(b,a.f[b;a];a.b[a];X) ∈ EClass(B))

Lemma: is-accum-class
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[b,f:Top]. ∀[e:E].  (e ∈b accum-class(b,a.f[b;a];a.b[a];X) e ∈b X)

Lemma: accum-class-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[base,f:Top]. ∀[e:E].
  accum-class(a,x.f[a;x];x.base[x];X)(e) accum_list(a,e.f[a;X(e)];e.base[X(e)];≤(X)(e)) 
  supposing ↑e ∈b accum-class(a,x.f[a;x];x.base[x];X)

Definition: max-f-class
(v from with maximum f[v]) ==  accum-class(v1,v2.if f[v1] <f[v2] then v2 else v1 fi v.v; X)

Lemma: max-f-class_wf
[Info,A:Type]. ∀[f:A ⟶ ℤ]. ∀[X:EClass(A)].  ((v from with maximum f[v]) ∈ EClass(A))

Lemma: is-max-f-class
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[f:Top]. ∀[X:EClass(A)]. ∀[e:E].
  (e ∈b (v from with maximum f[v]) e ∈b X)

Lemma: max-f-class-val
[Info:Type]. ∀[es:EO+(Info)]. ∀[A:Type]. ∀[f:A ⟶ ℤ]. ∀[X:EClass(A)]. ∀[e:E].
  (v from with maximum f[v])(e) accum_list(v,e.if f[v] <f[X(e)] then X(e) else fi ;e.X(e);≤(X)(e)) 
  supposing ↑e ∈b (v from with maximum f[v])

Definition: max-fst-class
MaxFst(X) ==  (p from with maximum fst(p))

Lemma: max-fst-class_wf
[Info,A,T:Type].  ∀[X:EClass(T × A)]. (MaxFst(X) ∈ EClass(T × A)) supposing T ⊆r ℤ

Lemma: is-max-fst
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].  (e ∈b MaxFst(X) e ∈b X)

Lemma: max-fst-val
[Info,A,T:Type].
  ∀[es:EO+(Info)]. ∀[X:EClass(T × A)]. ∀[e:E].
    MaxFst(X)(e) accum_list(p1,e.if fst(p1) <fst(X(e)) then X(e) else p1 fi ;e.X(e);≤(X)(e)) 
    supposing ↑e ∈b MaxFst(X) 
  supposing T ⊆r ℤ

Definition: es-interface-unmatched
es-interface-unmatched(A; B; R) ==
  es-interface-accum(λL,v. let L' if oob-hasleft(v) then [oob-getleft(v)] else fi  in
                               if oob-hasright(v) then remove-first(λa.(R oob-getright(v));L') else L' fi ;[];(A B))

Lemma: es-interface-unmatched_wf
[Info,Ta,Tb:Type]. ∀[A:EClass(Ta)]. ∀[B:EClass(Tb)]. ∀[R:Ta ⟶ Tb ⟶ 𝔹].
  (es-interface-unmatched(A; B; R) ∈ EClass(Ta List))

Definition: es-interface-locs-list
es-interface-locs-list(es;X;S) ==  ∀e:E(X). (loc(e) ∈ S)

Lemma: es-interface-locs-list_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[S:Id List]. ∀[X:EClass(Top)].  (es-interface-locs-list(es;X;S) ∈ ℙ)

Definition: information-flow-relation
information-flow-relation(es;X;F;e;i) ==  ↑can-apply(F loc(e) i;X(≤(X)(e)))

Lemma: information-flow-relation_wf
[Info,T:Type]. ∀[S:Id List]. ∀[F:information-flow(T;S)]. ∀[es:EO+(Info)]. ∀[X:EClass(T)].
  ∀[i:{i:Id| (i ∈ S)} ]. ∀[e:E(X)].  (information-flow-relation(es;X;F;e;i) ∈ ℙsupposing es-interface-locs-list(es;X;S\000C)

Lemma: flow-graph-information-flow-relation
[Info,T:Type].
  ∀S:Id List. ∀G:Graph(S). ∀F:information-flow(T;S). ∀es:EO+(Info). ∀X:EClass(T). ∀e:E(X). ∀i:Id.
    ((i ∈ S)
     es-interface-locs-list(es;X;S)
     flow-graph(S;T;F;G)
     (loc(e)⟶i)∈supposing information-flow-relation(es;X;F;e;i))

Definition: information-flow-to
information-flow-to(es;X;F;e;i) ==  do-apply(F loc(e) i;X(≤(X)(e)))

Lemma: information-flow-to_wf
[Info,T:Type]. ∀[S:Id List]. ∀[F:information-flow(T;S)]. ∀[es:EO+(Info)]. ∀[X:EClass(T)].
  ∀[i:{i:Id| (i ∈ S)} ]. ∀[e:E(X)].  information-flow-to(es;X;F;e;i) ∈ supposing information-flow-relation(es;X;F;e;i)\000C 
  supposing es-interface-locs-list(es;X;S)

Definition: solves-information-flow
solves-information-flow(es;T;S;F;In;X;f) ==
  (E(In) ⊆E(X))
  ∧ es-interface-locs-list(es;X;S)
  ∧ (∀e:E(X)
       ((((f e) e ∈ E(X) ⇐⇒ ↑e ∈b In) ∧ ((↑e ∈b In)  (X(e) In(e) ∈ T)))
       ∧ ((¬((f e) e ∈ E(X)))
          (information-flow-relation(es;X;F;f e;loc(e)) ∧ (X(e) information-flow-to(es;X;F;f e;loc(e)) ∈ T)))))
  ∧ (∀e:E(X). ∀i:Id.
       ((i ∈ S)
        information-flow-relation(es;X;F;e;i)
        (∃e':E(X). ((loc(e') i ∈ Id) ∧ ((f e') e ∈ E(X)) ∧ (e' e ∈ E(X)))))))

Lemma: solves-information-flow_wf
[Info,T:Type]. ∀[S:Id List]. ∀[F:information-flow(T;S)]. ∀[es:EO+(Info)]. ∀[In,X:EClass(T)]. ∀[f:sys-antecedent(es;X)].
  (solves-information-flow(es;T;S;F;In;X;f) ∈ ℙ)

Definition: fifo-information-flow
fifo-information-flow(es;T;S;F;In;X;f) ==
  solves-information-flow(es;T;S;F;In;X;f)
  ∧ (∀e1,e2:E(X).
       ((¬((f e1) e1 ∈ E(X)))
        ((f e2) e2 ∈ E(X)))
        (f e1 <loc e2)
        (loc(e1) loc(e2) ∈ Id)
        (e1 <loc e2)))

Lemma: fifo-information-flow_wf
[Info,T:Type]. ∀[S:Id List]. ∀[F:information-flow(T;S)]. ∀[es:EO+(Info)]. ∀[In,X:EClass(T)]. ∀[f:sys-antecedent(es;X)].
  (fifo-information-flow(es;T;S;F;In;X;f) ∈ ℙ)

Lemma: nonempty-es-interface-history
[Info:Type]
  ∀es:EO+(Info)
    ∀[A:Type]
      ∀X:EClass(A List). ∀e:E.
        (0 < ||es-interface-history(es;X;e)|| ⇐⇒ ∃e':E. (((↑e' ∈b X) ∧ e' ≤loc ) ∧ 0 < ||X(e')||))

Lemma: es-interface-from-decidable
[Info:Type]. ∀[A:es:EO+(Info) ⟶ e:E ⟶ Type]. ∀[R:es:EO+(Info) ⟶ e:E ⟶ A[es;e] ⟶ ℙ].
  ((∀es:EO+(Info). ∀e:E.  Dec(∃a:A[es;e]. R[es;e;a]))
   (∃X:EClass(A[es;e]). ∀es:EO+(Info). ∀e:E.  ((↑e ∈b ⇐⇒ ∃a:A[es;e]. R[es;e;a]) ∧ R[es;e;X(e)] supposing ↑e ∈b X)))

Lemma: es-interface-local-pred
[Info:Type]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ].
  ((∀es:EO+(Info). ∀e:E.  Dec(P es e))
   (∃X:EClass(E)
       ∀es:EO+(Info). ∀e:E.
         ((↑e ∈b ⇐⇒ ∃a:E. (es-p-local-pred(es;P es) a)) ∧ es-p-local-pred(es;P es) X(e) supposing ↑e ∈b X)))

Lemma: es-interface-le-pred
[Info:Type]. ∀[P:es:EO+(Info) ⟶ E ⟶ ℙ].
  ((∀es:EO+(Info). ∀e:E.  Dec(P es e))
   (∃X:EClass({e:E| es e} )
       ∀es:EO+(Info). ∀e:E.
         ((↑e ∈b ⇐⇒ ∃a:{e:E| es e} (es-p-le-pred(es;P es) a))
         ∧ es-p-le-pred(es;P es) X(e) supposing ↑e ∈b X)))

Lemma: es-interface-le-pred-bool
[Info:Type]
  ∀P:es:EO+(Info) ⟶ E ⟶ 𝔹
    ∃X:EClass({e:E| ↑(P es e)} )
     ∀es:EO+(Info). ∀e:E.
       ((↑e ∈b ⇐⇒ ∃a:E. (es-p-le-pred(es;λe.(↑(P es e))) a))
       ∧ es-p-le-pred(es;λe.(↑(P es e))) X(e) supposing ↑e ∈b X)

Definition: es-local-pred
last(P) ==
  fix((λes-local-pred,e. if first(e) then inr x.⋅)  if pred(e) then inl pred(e) else es-local-pred pred(e) fi ))

Lemma: es-local-pred_wf2
[Info:Type]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[P:{e':E| (e' <loc e)}  ⟶ 𝔹].
  (last(P) e ∈ (∃e':{E| ((e' <loc e) ∧ (↑(P e')) ∧ (∀e'':E. ((e' <loc e'')  (e'' <loc e)  (¬↑(P e'')))))})
   ∨ (∃e':{E| ((e' <loc e) ∧ (↑(P e')))})))

Lemma: es-local-pred_wf
[Info:Type]. ∀[es:EO+(Info)]. ∀[P:E ⟶ 𝔹].
  (last(P) ∈ e:E ⟶ ((∃e':{E| ((e' <loc e) ∧ (↑(P e')) ∧ (∀e'':E. ((e' <loc e'')  (e'' <loc e)  (¬↑(P e'')))))})
                    ∨ (∃e':{E| ((e' <loc e) ∧ (↑(P e')))}))))

Definition: class-pred
class-pred(X;es;e) ==  last(λe'.0 <#(X es e')) e

Lemma: class-pred_wf
[Info:Type]. ∀[X:EClass(Top)]. ∀[es:EO+(Info)]. ∀[e:E].  (class-pred(X;es;e) ∈ Top)

Lemma: class-pred-cases
[Info,T:Type].
  ∀X:EClass(T). ∀es:EO+(Info). ∀e:E.
    (∃e'<e.((↓∃v:T. v ∈ X(e')) ∧ ∀e''<e.(↓∃v:T. v ∈ X(e''))  e'' ≤loc e' )
    ∧ (class-pred(X;es;e) (inl e') ∈ (E Top))
    ∨ (∀e'<e.∀v:T. v ∈ X(e')) ∧ (class-pred(X;es;e) (inr ⋅ ) ∈ (E Top))))

Definition: until-class
(X until Y) ==  λes,e. case class-pred(Y;es;e) of inl(e') => {} inr(z) => es e

Lemma: until-class_wf
[Info,A:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(Top)].  ((X until Y) ∈ EClass(A))

Lemma: until-classrel
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:A].
  (v ∈ (X until Y)(e) ⇐⇒ (no prior to e) ∧ v ∈ X(e))

Definition: once-class
(X once) ==  (X until X)

Lemma: once-class_wf
[Info,A:Type]. ∀[X:EClass(A)].  ((X once) ∈ EClass(A))

Lemma: once-once-class
[Info,A:Type]. ∀[X:EClass(A)].  (((X once) once) (X once) ∈ EClass(A))

Lemma: once-classrel
[Info,A:Type]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E].  ∀v:A. uiff(v ∈ (X once)(e);(no prior to e) ∧ v ∈ X(e))

Lemma: once-classrel-weak
[Info,A:Type]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E].  ∀v:A. (v ∈ (X once)(e) ⇐⇒ (no prior to e) ∧ v ∈ {X}(e))

Definition: send-once-class
Send(b) ==  es,e. once)

Lemma: send-once-class_wf
[Info,A:Type]. ∀[b:bag(A)].  (Send(b) ∈ EClass(A))

Definition: send-once-loc-class
send-once-loc-class(b) ==  es,e. (b loc(e)) once)

Lemma: send-once-loc-class_wf
[Info,A:Type]. ∀[b:Id ⟶ bag(A)].  (send-once-loc-class(b) ∈ EClass(A))

Lemma: send-once-classrel
[Info,A:Type]. ∀[b:bag(A)].  ∀es:EO+(Info). ∀e:E. ∀v:A.  (v ∈ Send(b)(e) ⇐⇒ v ↓∈ b ∧ (↑first(e)))

Lemma: send-once-loc-classrel
[Info,A:Type]. ∀[b:Id ⟶ bag(A)].
  ∀es:EO+(Info). ∀e:E. ∀v:A.  (v ∈ send-once-loc-class(b)(e) ⇐⇒ v ↓∈ loc(e) ∧ (↑first(e)))

Lemma: send-once-no-prior-classrel
[Info,A:Type].  ∀b:bag(A). ∀es:EO+(Info). ∀e:E.  ((no Send(b) prior to e) ⇐⇒ (↑first(e)) ∨ (↑bag-null(b)))

Definition: on-loc-class
on-loc-class(X) ==  λes,e. (X loc(e) es e)

Lemma: on-loc-class_wf
[Info,T:Type]. ∀[X:Id ⟶ EClass(T)].  (on-loc-class(X) ∈ EClass(T))

Definition: but-first-class
Skip-e(X) ==  λes,e. if first(e) then {} else es>es-init(es;e) fi 

Lemma: but-first-class_wf
[Info,A:Type]. ∀[X:EClass(A)].  (Skip-e(X) ∈ EClass(A))

Definition: skip-first-class
Skip(X) ==  λes,e. if first(e) then {} else es fi 

Lemma: skip-first-class_wf
[Info,A:Type]. ∀[X:EClass(A)].  (Skip(X) ∈ EClass(A))

Lemma: skip-first-class-property
[Info,A:Type]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[X:EClass(A)]. ∀[a:A].  a ∈ Skip(X)(e))

Lemma: skip-first-class-property-iff
[Info,A:Type]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[X:EClass(A)]. ∀[a:A].  uiff(a ∈ Skip(X)(e);False)

Lemma: skip-first-class-is-empty-if-first
[Info,A:Type]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[X:EClass(A)].  Skip(X) es {} supposing ↑first(e)

Definition: local-pred-class
local-pred-class(P) ==  λes,e. case last(P es) of inl(e') => {e'} inr(x) => {}

Lemma: local-pred-class_wf
[Info:Type]. ∀[P:es:EO+(Info) ⟶ E ⟶ 𝔹].
  (local-pred-class(P) ∈ EClass({e':E| 
                                 (e' <loc e)
                                 ∧ (↑(P es e'))
                                 ∧ (∀e'':E. ((e' <loc e'')  (e'' <loc e)  (¬↑(P es e''))))} ))

Lemma: es-local-pred-property2
[Info:Type]
  ∀es:EO+(Info). ∀e:E. ∀P:{e':E| (e' <loc e)}  ⟶ 𝔹.
    ((↑can-apply(last(P);e) ⇐⇒ ∃a:E. ((a <loc e) ∧ (↑(P a))))
    ∧ (do-apply(last(P);e) <loc e)
      ∧ (↑(P do-apply(last(P);e)))
      ∧ (∀e'':E. ((e'' <loc e)  (do-apply(last(P);e) <loc e'')  (¬↑(P e'')))) 
      supposing ↑can-apply(last(P);e))

Lemma: es-local-pred-cases-sq
[Info:Type]
  ∀es:EO+(Info). ∀e:E. ∀P:{e':E| (e' <loc e)}  ⟶ 𝔹.
    (¬↑first(e))
    ∧ (((↑(P pred(e))) ∧ (do-apply(last(P);e) pred(e)))
      ∨ ((¬↑(P pred(e))) ∧ (↑can-apply(last(P);pred(e))) ∧ (do-apply(last(P);e) do-apply(last(P);pred(e))))) 
    supposing ↑can-apply(last(P);e)

Lemma: es-local-pred-cases
[Info:Type]
  ∀es:EO+(Info). ∀e:E. ∀P:{e':E| (e' <loc e)}  ⟶ 𝔹.
    (¬↑first(e))
    ∧ (((↑(P pred(e))) ∧ (do-apply(last(P);e) pred(e) ∈ E))
      ∨ ((¬↑(P pred(e))) ∧ (↑can-apply(last(P);pred(e))) ∧ (do-apply(last(P);e) do-apply(last(P);pred(e)) ∈ E))) 
    supposing ↑can-apply(last(P);e)

Lemma: es-local-pred-property
[Info:Type]
  ∀es:EO+(Info). ∀e:E. ∀P:{e':E| (e' <loc e)}  ⟶ 𝔹.
    ((↑can-apply(last(P);e) ⇐⇒ ∃a:E. ((a <loc e) ∧ (↑(P a))))
    ∧ (do-apply(last(P);e) <loc e)
      ∧ (↑(P do-apply(last(P);e)))
      ∧ (∀e'':E. ((e'' <loc e)  (do-apply(last(P);e) <loc e'')  (¬↑(P e'')))) 
      supposing ↑can-apply(last(P);e))

Lemma: es-interface-local-pred-bool
[Info:Type]
  ∀P:es:EO+(Info) ⟶ E ⟶ 𝔹
    ∃X:EClass({e':E| (e' <loc e) ∧ (↑(P es e')) ∧ (∀e'':E. ((e' <loc e'')  (e'' <loc e)  (¬↑(P es e''))))} )
     ∀es:EO+(Info). ∀e:E.
       ((↑e ∈b ⇐⇒ ∃a:E. ((a <loc e) ∧ (↑(P es a)))) ∧ es-p-local-pred(es;λe.(↑(P es e))) X(e) supposing ↑e ∈b X)

Definition: es-local-le-pred
(P) ==  fix((λes-local-le-pred,es,e. if es then {e} if first(e) then {} else es-local-le-pred es pred(e) fi ))

Lemma: es-local-le-pred_wf
[Info:Type]. ∀[P:es:EO+(Info) ⟶ E ⟶ 𝔹].  (≤(P) ∈ EClass({e:E| ↑(P es e)} ))

Lemma: es-local-le-pred-property
[Info:Type]
  ∀P:es:EO+(Info) ⟶ E ⟶ 𝔹. ∀es:EO+(Info). ∀e:E.
    ((↑e ∈b ≤(P) ⇐⇒ ∃a:E. (a ≤loc e  ∧ (↑(P es a))))
    ∧ ≤(P)(e) ≤loc e  ∧ (↑(P es ≤(P)(e))) ∧ (∀e'':E. (e'' ≤loc e   (≤(P)(e) <loc e'')  (¬↑(P es e'')))) 
      supposing ↑e ∈b ≤(P))

Definition: primed-class
Prior(X) ==  λes,e. case last(λe'.0 <#(X es e')) of inl(e') => es e' inr(x) => {}

Lemma: primed-class_wf
[Info,T:Type]. ∀[X:EClass(T)].  (Prior(X) ∈ EClass(T))

Definition: primed-class-opt
Prior(X)?b ==  λes,e. case last(λe'.0 <#(X es e')) of inl(e') => es e' inr(x) => loc(e)

Lemma: primed-class-opt_wf
[Info,T:Type]. ∀[b:Id ⟶ bag(T)]. ∀[X:EClass(T)].  (Prior(X)?b ∈ EClass(T))

Lemma: primed-class-opt-cases
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[b:Top]. ∀[e:E].
  (Prior(X)?b es if first(e) then loc(e)
  if 0 <#(X es pred(e)) then es pred(e)
  else Prior(X)?b es pred(e)
  fi )

Lemma: primed-class-opt-cases2
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[b:Top]. ∀[e:E].
  (Prior(X)?b(e) if first(e) then loc(e)
  if 0 <#(X(pred(e))) then X(pred(e))
  else Prior(X)?b(pred(e))
  fi )

Lemma: primed-class-opt_functionality
[Info,B:Type]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[X,Y:EClass(B)].
  Prior(X)?init(e) Prior(Y)?init(e) ∈ bag(B) supposing ∀e1:E. ((e1 < e)  (X(e1) Y(e1) ∈ bag(B)))

Lemma: primed-class-opt_functionality-locl
[Info,B:Type]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[X,Y:EClass(B)].
  Prior(X)?init(e) Prior(Y)?init(e) ∈ bag(B) supposing ∀e1:E. ((e1 <loc e)  (X(e1) Y(e1) ∈ bag(B)))

Lemma: primed-class-opt-classrel
[T,Info:Type]. ∀[X:EClass(T)]. ∀[init:Id ⟶ bag(T)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:T].
  uiff(v ∈ Prior(X)?init(e);↓(∃e':E. ((es-p-local-pred(es;λe'.(↓∃w:T. w ∈ X(e'))) e') ∧ v ∈ X(e')))
                             ∨ ((∀e':E. ((e' <loc e)  (∀w:T. w ∈ X(e'))))) ∧ v ↓∈ init loc(e)))

Definition: loop-class
loop-class(X;init) ==  fix((λloop-class.(X Prior(loop-class)?init)))

Lemma: loop-class_wf
[Info,B:Type]. ∀[X:EClass(B ⟶ bag(B))]. ∀[init:Id ⟶ bag(B)].  (loop-class(X;init) ∈ EClass(B))

Lemma: loop-classrel
[Info,B:Type]. ∀[X:EClass(B ⟶ bag(B))]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:B].
  uiff(v ∈ loop-class(X;init)(e);↓∃f:B ⟶ bag(B). ∃b:B. (f ∈ X(e) ∧ b ∈ Prior(loop-class(X;init))?init(e) ∧ v ↓∈ b))

Definition: loop-class2
loop-class2(X;init) ==  fix((λloop-class2.eclass3(X;Prior(loop-class2)?init)))

Lemma: loop-class2_wf
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)].  (loop-class2(X;init) ∈ EClass(B))

Lemma: loop2-classrel
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:B].
  uiff(v ∈ loop-class2(X;init)(e);↓∃f:B ⟶ B
                                    ∃b:B. (f ∈ X(e) ∧ b ∈ Prior(loop-class2(X;init))?init(e) ∧ (v (f b) ∈ B)))

Definition: loop-class-state
loop-class-state(X;init) ==  fix((λloop-class-state.eclass-cond(X;Prior(loop-class-state)?init)))

Lemma: loop-class-state_wf
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)].  (loop-class-state(X;init) ∈ EClass(B))

Lemma: loop-class-state-exists
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  uiff(0 < #(init loc(e));↓∃v:B. v ∈ loop-class-state(X;init)(e))

Lemma: loop-class-state-prior
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)].
  ∀es:EO+(Info). ∀e:E.
    ∀[v:B]
      uiff(v ∈ Prior(loop-class-state(X;init))?init(e);((↑first(e)) ∧ v ↓∈ init loc(e))
      ∨ ((¬↑first(e)) ∧ v ∈ loop-class-state(X;init)(pred(e))))

Lemma: loop-class-state-classrel
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:B].
  uiff(v ∈ loop-class-state(X;init)(e);↓∃b:B
                                         (if first(e)
                                         then b ↓∈ init loc(e)
                                         else b ∈ loop-class-state(X;init)(pred(e))
                                         fi 
                                         ∧ if e ∈b then ∃f:B ⟶ B. (f ∈ X(e) ∧ (v (f b) ∈ B)) else b ∈ fi ))

Lemma: loop-class-state-total
[Info,B:Type]. ∀[init:Id ⟶ bag(B)]. ∀[X:EClass(B ⟶ B)]. ∀[es:EO+(Info)].
  es-total-class(es;loop-class-state(X;init)) supposing ∀l:Id. (1 ≤ #(init l))

Lemma: loop-class-state-single-val
[Info,B:Type]. ∀[init:Id ⟶ bag(B)]. ∀[X:EClass(B ⟶ B)]. ∀[es:EO+(Info)].
  (single-valued-classrel(es;loop-class-state(X;init);B)) supposing 
     ((∀l:Id. single-valued-bag(init l;B)) and 
     single-valued-classrel(es;X;B ⟶ B))

Lemma: loop-class-state-functional
[Info,B:Type]. ∀[init:Id ⟶ bag(B)]. ∀[X:EClass(B ⟶ B)]. ∀[es:EO+(Info)].
  (loop-class-state(X;init) is functional) supposing 
     ((∀l:Id. single-valued-bag(init l;B)) and 
     single-valued-classrel(es;X;B ⟶ B) and 
     (∀l:Id. (1 ≤ #(init l))))

Lemma: loop-class-state-fun-eq
[Info,B:Type]. ∀[init:Id ⟶ bag(B)]. ∀[X:EClass(B ⟶ B)]. ∀[es:EO+(Info)]. ∀[e:E].
  (loop-class-state(X;init)(e)
     if e ∈b then if first(e) then X@e sv-bag-only(init loc(e)) else X@e loop-class-state(X;init)(pred(e)) fi 
       if first(e) then sv-bag-only(init loc(e))
       else loop-class-state(X;init)(pred(e))
       fi 
     ∈ B) supposing 
     ((∀l:Id. single-valued-bag(init l;B)) and 
     single-valued-classrel(es;X;B ⟶ B) and 
     (∀l:Id. (1 ≤ #(init l))))

Definition: loop-class-memory
loop-class-memory(X;init) ==  fix((λloop-class-memory.Prior(eclass3(X;loop-class-memory))?init))

Lemma: loop-class-memory_wf
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)].  (loop-class-memory(X;init) ∈ EClass(B))

Lemma: loop-class-memory-exists
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  uiff(0 < #(init loc(e));↓∃v:B. v ∈ loop-class-memory(X;init)(e))

Lemma: loop-class-memory-size
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  uiff(0 < #(init loc(e));0 < #(loop-class-memory(X;init)(e)))

Lemma: loop-class-memory-member
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  uiff(0 < #(init loc(e));↑e ∈b loop-class-memory(X;init))

Lemma: loop-class-memory-size-zero
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  uiff(#(init loc(e)) 0 ∈ ℤ;#(loop-class-memory(X;init)(e)) 0 ∈ ℤ)

Lemma: loop-class-memory-prior
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)].
  ∀es:EO+(Info). ∀e:E.
    ∀[v:B]
      uiff(v ∈ Prior(loop-class-memory(X;init))?init(e);((↑first(e)) ∧ v ↓∈ init loc(e))
      ∨ ((¬↑first(e)) ∧ v ∈ loop-class-memory(X;init)(pred(e))))

Lemma: loop-class-memory-exists-prior
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  uiff(0 < #(init loc(e));↓∃v:B. v ∈ Prior(loop-class-memory(X;init))?init(e))

Lemma: loop-class-memory-size-prior
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  uiff(0 < #(init loc(e));0 < #(Prior(loop-class-memory(X;init))?init(e)))

Lemma: loop-class-memory-prior-eq
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  (Prior(loop-class-memory(X;init))?init(e)
  if first(e) then init loc(e) else loop-class-memory(X;init)(pred(e)) fi 
  ∈ bag(B))

Lemma: loop-class-memory-classrel
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:B].
  uiff(v ∈ loop-class-memory(X;init)(e);↓if first(e)
                                         then v ↓∈ init loc(e)
                                         else ∃b:B
                                               (b ∈ loop-class-memory(X;init)(pred(e))
                                               ∧ if pred(e) ∈b X
                                                 then ∃f:B ⟶ B. (f ∈ X(pred(e)) ∧ (v (f b) ∈ B))
                                                 else b ∈ B
                                                 fi )
                                         fi )

Lemma: loop-class-memory-no-input
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  loop-class-memory(X;init)(e) Prior(loop-class-memory(X;init))?init(e) ∈ bag(B) 
  supposing (¬↑first(e))  (¬↑pred(e) ∈b X)

Lemma: loop-class-memory-eq
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  (loop-class-memory(X;init)(e)
  if first(e) then init loc(e)
    if pred(e) ∈b then eclass3(X;loop-class-memory(X;init))(pred(e))
    else loop-class-memory(X;init)(pred(e))
    fi 
  ∈ bag(B))

Lemma: loop-class-memory-total
[Info,B:Type]. ∀[init:Id ⟶ bag(B)]. ∀[X:EClass(B ⟶ B)]. ∀[es:EO+(Info)].
  es-total-class(es;loop-class-memory(X;init)) supposing ∀l:Id. (1 ≤ #(init l))

Lemma: loop-class-memory-single-val
[Info,B:Type]. ∀[init:Id ⟶ bag(B)]. ∀[X:EClass(B ⟶ B)]. ∀[es:EO+(Info)].
  (single-valued-classrel(es;loop-class-memory(X;init);B)) supposing 
     ((∀l:Id. single-valued-bag(init l;B)) and 
     single-valued-classrel(es;X;B ⟶ B))

Lemma: loop-class-memory-functional
[Info,B:Type]. ∀[init:Id ⟶ bag(B)]. ∀[X:EClass(B ⟶ B)]. ∀[es:EO+(Info)].
  (loop-class-memory(X;init) is functional) supposing 
     ((∀l:Id. single-valued-bag(init l;B)) and 
     single-valued-classrel(es;X;B ⟶ B) and 
     (∀l:Id. (1 ≤ #(init l))))

Lemma: loop-class-memory-is-prior-loop-class-state
[Info,B:Type]. ∀[X:EClass(B ⟶ B)]. ∀[init:Id ⟶ bag(B)].
  (loop-class-memory(X;init) Prior(loop-class-state(X;init))?init ∈ EClass(B))

Definition: eclass-disju
==  l,x. (inl x) X) || l,x. (inr Y)

Lemma: eclass-disju_wf
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].  (X Y ∈ EClass(A B))

Lemma: eclass-disju-classrel
[Info,A,B:Type]. ∀[X:EClass(A)]. ∀[Y:EClass(B)]. ∀[es:EO+(Info)]. ∀[e:E].
  ∀v:A B. uiff(v ∈ Y(e);((↑isl(v)) ∧ outl(v) ∈ X(e)) ∨ ((¬↑isl(v)) ∧ outr(v) ∈ Y(e)))

Lemma: eclass-disju-bind-left
[Info,A1,A2,B:Type]. ∀[X1:EClass(A1)]. ∀[X2:EClass(A2)]. ∀[Y1:A1 ⟶ EClass(B)]. ∀[Y2:A2 ⟶ EClass(B)].
  (X1 X2 >x> case of inl(a1) => Y1[a1] inr(a2) => Y2[a2] X1 >x> Y1[x] || X2 >x> Y2[x] ∈ EClass(B))

Definition: state-class1
state-class1(init;tr;X) ==  loop-class-state((tr X);λloc.{init loc})

Lemma: state-class1_wf
[Info,A,B:Type]. ∀[init:Id ⟶ B]. ∀[f:Id ⟶ A ⟶ B ⟶ B]. ∀[X:EClass(A)].  (state-class1(init;f;X) ∈ EClass(B))

Definition: state-class2
state-class2(init;tr1;X1;tr2;X2) ==  loop-class-state((tr1 X1) || (tr2 X2);λloc.{init loc})

Lemma: state-class2_wf
[Info,A1,A2,B:Type]. ∀[init:Id ⟶ B]. ∀[tr1:Id ⟶ A1 ⟶ B ⟶ B]. ∀[X1:EClass(A1)]. ∀[tr2:Id ⟶ A2 ⟶ B ⟶ B].
[X2:EClass(A2)].
  (state-class2(init;tr1;X1;tr2;X2) ∈ EClass(B))

Definition: state-class3
state-class3(init;tr1;X1;tr2;X2;tr3;X3) ==  loop-class-state((tr1 X1) || (tr2 X2) || (tr3 X3);λloc.{init loc})

Lemma: state-class3_wf
[Info,A1,A2,A3,B:Type]. ∀[init:Id ⟶ B]. ∀[tr1:Id ⟶ A1 ⟶ B ⟶ B]. ∀[X1:EClass(A1)]. ∀[tr2:Id ⟶ A2 ⟶ B ⟶ B].
[X2:EClass(A2)]. ∀[tr3:Id ⟶ A3 ⟶ B ⟶ B]. ∀[X3:EClass(A3)].
  (state-class3(init;tr1;X1;tr2;X2;tr3;X3) ∈ EClass(B))

Definition: state-class4
state-class4(init;tr1;X1;tr2;X2;tr3;X3;tr4;X4) ==
  loop-class-state((tr1 X1) || (tr2 X2) || (tr3 X3) || (tr4 X4);λloc.{init loc})

Lemma: state-class4_wf
[Info,A1,A2,A3,A4,B:Type]. ∀[init:Id ⟶ B]. ∀[tr1:Id ⟶ A1 ⟶ B ⟶ B]. ∀[X1:EClass(A1)]. ∀[tr2:Id ⟶ A2 ⟶ B ⟶ B].
[X2:EClass(A2)]. ∀[tr3:Id ⟶ A3 ⟶ B ⟶ B]. ∀[X3:EClass(A3)]. ∀[tr4:Id ⟶ A4 ⟶ B ⟶ B]. ∀[X4:EClass(A4)].
  (state-class4(init;tr1;X1;tr2;X2;tr3;X3;tr4;X4) ∈ EClass(B))

Definition: state-class5
state-class5(init;tr1;X1;tr2;X2;tr3;X3;tr4;X4;tr5;X5) ==
  loop-class-state((tr1 X1) || (tr2 X2) || (tr3 X3) || (tr4 X4) || (tr5 X5);λloc.{init loc})

Lemma: state-class5_wf
[Info,A1,A2,A3,A4,A5,B:Type]. ∀[init:Id ⟶ B]. ∀[tr1:Id ⟶ A1 ⟶ B ⟶ B]. ∀[X1:EClass(A1)]. ∀[tr2:Id ⟶ A2 ⟶ B ⟶ B].
[X2:EClass(A2)]. ∀[tr3:Id ⟶ A3 ⟶ B ⟶ B]. ∀[X3:EClass(A3)]. ∀[tr4:Id ⟶ A4 ⟶ B ⟶ B]. ∀[X4:EClass(A4)]. ∀[tr5:Id
                                                                                                                  ⟶ A5
                                                                                                                  ⟶ B
                                                                                                                  ⟶ B].
[X5:EClass(A5)].
  (state-class5(init;tr1;X1;tr2;X2;tr3;X3;tr4;X4;tr5;X5) ∈ EClass(B))

Definition: memory-class1
memory-class1(initially initapplying tron X) ==  loop-class-memory((tr X);λloc.{init loc})

Lemma: memory-class1_wf
[Info,A,B:Type]. ∀[init:Id ⟶ B]. ∀[f:Id ⟶ A ⟶ B ⟶ B]. ∀[X:EClass(A)].
  (memory-class1(initially init
                 applying f
                 on X) ∈ EClass(B))

Definition: memory-class2
memory-class2(init;tr1;X1;tr2;X2) ==  loop-class-memory((tr1 X1) || (tr2 X2);λloc.{init loc})

Lemma: memory-class2_wf
[Info,A1,A2,B:Type]. ∀[init:Id ⟶ B]. ∀[tr1:Id ⟶ A1 ⟶ B ⟶ B]. ∀[X1:EClass(A1)]. ∀[tr2:Id ⟶ A2 ⟶ B ⟶ B].
[X2:EClass(A2)].
  (memory-class2(init;tr1;X1;tr2;X2) ∈ EClass(B))

Definition: memory-class3
memory-class3(init;tr1;X1;tr2;X2;tr3;X3) ==  loop-class-memory((tr1 X1) || (tr2 X2) || (tr3 X3);λloc.{init loc})

Lemma: memory-class3_wf
[Info,A1,A2,A3,B:Type]. ∀[init:Id ⟶ B]. ∀[tr1:Id ⟶ A1 ⟶ B ⟶ B]. ∀[X1:EClass(A1)]. ∀[tr2:Id ⟶ A2 ⟶ B ⟶ B].
[X2:EClass(A2)]. ∀[tr3:Id ⟶ A3 ⟶ B ⟶ B]. ∀[X3:EClass(A3)].
  (memory-class3(init;tr1;X1;tr2;X2;tr3;X3) ∈ EClass(B))

Definition: memory-class4
memory-class4(init;tr1;X1;tr2;X2;tr3;X3;tr4;X4) ==
  loop-class-memory((tr1 X1) || (tr2 X2) || (tr3 X3) || (tr4 X4);λloc.{init loc})

Lemma: memory-class4_wf
[Info,A1,A2,A3,A4,B:Type]. ∀[init:Id ⟶ B]. ∀[tr1:Id ⟶ A1 ⟶ B ⟶ B]. ∀[X1:EClass(A1)]. ∀[tr2:Id ⟶ A2 ⟶ B ⟶ B].
[X2:EClass(A2)]. ∀[tr3:Id ⟶ A3 ⟶ B ⟶ B]. ∀[X3:EClass(A3)]. ∀[tr4:Id ⟶ A4 ⟶ B ⟶ B]. ∀[X4:EClass(A4)].
  (memory-class4(init;tr1;X1;tr2;X2;tr3;X3;tr4;X4) ∈ EClass(B))

Definition: eclass-state
eclass-state(init;f;X) ==  loop-class((λi,a,b. {f b} X);λl.{init l})

Lemma: eclass-state_wf
[Info,A,B:Type]. ∀[init:Id ⟶ B]. ∀[f:Id ⟶ A ⟶ B ⟶ B]. ∀[X:EClass(A)].  (eclass-state(init;f;X) ∈ EClass(B))

Lemma: eclass-state-classrel
[Info,A,B:Type]. ∀[init:Id ⟶ B]. ∀[f:Id ⟶ A ⟶ B ⟶ B]. ∀[X:EClass(A)]. ∀[es:EO+(Info)]. ∀[e:E]. ∀[v:B].
  uiff(v ∈ eclass-state(init;f;X)(e);↓∃b:B
                                       ∃a:A
                                        (a ∈ X(e)
                                        ∧ b ∈ Prior(eclass-state(init;f;X))?λl.{init l}(e)
                                        ∧ (v (f loc(e) b) ∈ B)))

Definition: class-opt
X?b ==  λes,e. if bag-null(X es e) then loc(e) else es fi 

Lemma: class-opt_wf
[Info,T:Type]. ∀[X:EClass(T)]. ∀[b:Id ⟶ bag(T)].  (X?b ∈ EClass(T))

Definition: class-opt-class
X?Y ==  λes,e. if bag-null(X es e) then es else es fi 

Lemma: class-opt-class_wf
[Info,T:Type]. ∀[X,Y:EClass(T)].  (X?Y ∈ EClass(T))

Lemma: class-opt-opt
[Info,T:Type]. ∀[X:EClass(T)]. ∀[b:Id ⟶ bag(T)].  (X?b X?b?b ∈ EClass(T))

Lemma: primed-class-opt_eq_class-opt-primed
[Info,T:Type]. ∀[b:Id ⟶ bag(T)]. ∀[X:EClass(T)].  (Prior(X)?b Prior(X)?b ∈ EClass(T))

Lemma: primed-class-opt_eq_class-opt-class-primed
[Info,T:Type]. ∀[init:Id ⟶ bag(T)]. ∀[X:EClass(T)].  (Prior(X)?init Prior(X)?λl.init l| | ∈ EClass(T))

Definition: es-prior-interface
prior(X) ==  local-pred-class(λes,e. e ∈b X)

Lemma: es-prior-interface_wf1
[Info,T:Type]. ∀[X:EClass(T)].  (prior(X) ∈ EClass(E(X)))

Lemma: es-prior-interface_wf
[Info:Type]. ∀[X:EClass(Top)].  (prior(X) ∈ EClass(E(X)))

Lemma: es-prior-interface_wf0
[Info:Type]. ∀[X:EClass(Top)].  (prior(X) ∈ EClass(E))

Lemma: is-prior-interface
[Info:Type]. ∀X:EClass(Top). ∀es:EO+(Info). ∀e:E.  (↑e ∈b prior(X) ⇐⇒ ∃e':E. ((e' <loc e) ∧ (↑e' ∈b X)))

Lemma: es-prior-interface-cases
[Info:Type]
  ∀X:EClass(Top). ∀es:EO+(Info). ∀e:E.
    (¬↑first(e))
    ∧ (((↑pred(e) ∈b X) ∧ (prior(X)(e) pred(e) ∈ E))
      ∨ ((¬↑pred(e) ∈b X) ∧ (↑pred(e) ∈b prior(X)) ∧ (prior(X)(e) prior(X)(pred(e)) ∈ E))) 
    supposing ↑e ∈b prior(X)

Lemma: es-prior-interface-cases-sq
[Info:Type]
  ∀X:EClass(Top). ∀es:EO+(Info). ∀e:E.
    (¬↑first(e))
    ∧ (((↑pred(e) ∈b X) ∧ (prior(X)(e) pred(e)))
      ∨ ((¬↑pred(e) ∈b X) ∧ (↑pred(e) ∈b prior(X)) ∧ (prior(X)(e) prior(X)(pred(e))))) 
    supposing ↑e ∈b prior(X)

Lemma: es-interface-predecessors-nil
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].
  (≤(X)(pred(e)) []) supposing ((¬↑first(e)) and (¬↑e ∈b prior(X)))

Definition: es-le-interface
le(X) ==  ≤es,e. e ∈b X)

Lemma: es-le-interface_wf
[Info,A:Type]. ∀[X:EClass(A)].  (le(X) ∈ EClass(E(X)))

Lemma: es-is-prior-interface
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E.  (↑e ∈b prior(X) ⇐⇒ ∃e':E. ((e' <loc e) ∧ (↑e' ∈b X)))

Lemma: es-is-prior-interface-pred
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E.  (↑e ∈b prior(X) ⇐⇒ (¬↑first(e)) ∧ ((↑pred(e) ∈b X) ∨ (↑pred(e) ∈b prior(X))))

Lemma: es-is-le-interface
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E.  (↑e ∈b le(X) ⇐⇒ ∃e':E. (e' ≤loc e  ∧ (↑e' ∈b X)))

Lemma: es-is-le-interface-iff
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E.  (↑e ∈b le(X) ⇐⇒ (↑e ∈b prior(X)) ∨ (↑e ∈b X))

Lemma: es-prior-interface-val
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E.
    (prior(X)(e) <loc e) ∧ (↑prior(X)(e) ∈b X) ∧ (∀e'':E. ((e'' <loc e)  (prior(X)(e) <loc e'')  (¬↑e'' ∈b X))) 
    supposing ↑e ∈b prior(X)

Lemma: es-prior-interface-val-unique
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].
  ∀[p:E]
    prior(X)(e) ∈ supposing (p <loc e) ∧ (↑p ∈b X) ∧ (∀e'':E. ((e'' <loc e)  (p <loc e'')  (¬↑e'' ∈b X))) 
  supposing ↑e ∈b prior(X)

Lemma: es-prior-interface-val-unique2
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].
  ∀[p:E]. (prior(X)(p) prior(X)(e) ∈ E) supposing ((p <loc e) and (prior(X)(e) <loc p)) supposing ↑e ∈b prior(X)

Lemma: es-prior-interface-equal
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y:EClass(Top)]. ∀[e:E].
  (prior(X)(e) prior(Y)(e) ∈ E) supposing 
     ((∀e':E. (((prior(X)(e) <loc e') ∨ (prior(Y)(e) <loc e'))  (e' <loc e)  (↑e' ∈b ⇐⇒ ↑e' ∈b Y))) and 
     (↑e ∈b prior(X)) and 
     (↑e ∈b prior(Y)))

Lemma: es-prior-interface-same
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y:EClass(Top)].
  (∀[e:E]. uiff(↑e ∈b prior(X);↑e ∈b prior(Y))) ∧ (∀[e:E]. prior(Y)(e) prior(X)(e) ∈ supposing ↑e ∈b prior(X)) 
  supposing ∀e:E. (↑e ∈b ⇐⇒ ↑e ∈b Y)

Lemma: first-interface-implies-prior-interface
[Info:Type]. ∀[es:EO+(Info)]. ∀[X,Y:EClass(Top)].
  ∀[e:E]. ↑e ∈b prior(Y) supposing ↑e ∈b prior(X) supposing ∀e:E. ((↑e ∈b X)  (¬↑e ∈b prior(X))  (↑e ∈b Y))

Lemma: es-le-interface-val
[Info:Type]
  ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E.
    le(X)(e) ≤loc e  ∧ (↑le(X)(e) ∈b X) ∧ (∀e'':E. (e'' ≤loc e   (le(X)(e) <loc e'')  (¬↑e'' ∈b X))) 
    supposing ↑e ∈b le(X)

Lemma: es-le-interface-val-cases
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].  (le(X)(e) if e ∈b then else prior(X)(e) fi )

Lemma: es-prior-interface-val-pred
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].
  prior(X)(e) if pred(e) ∈b then pred(e) else prior(X)(pred(e)) fi  ∈ supposing ↑e ∈b prior(X)

Lemma: es-prior-interface-locl
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E.  (prior(X)(e) <loc e) supposing ↑e ∈b prior(X)

Lemma: es-loc-prior-interface
[Info:Type]. ∀[es:EO+(Info)]. ∀[X:EClass(Top)]. ∀[e:E].  loc(prior(X)(e)) loc(e) ∈ Id supposing ↑e ∈b prior(X)

Lemma: es-prior-interface-causl
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E.  (prior(X)(e) < e) supposing ↑e ∈b prior(X)

Lemma: es-le-prior-interface-val
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E. ∀e':E(X).  ((e' <loc e)  e' ≤loc prior(X)(e) )

Lemma: es-prior-interface-val-locl
[Info:Type]. ∀es:EO+(Info). ∀X:EClass(Top). ∀e:E(prior(X)). ∀e':E(X).  ((prior(X)(e) <loc e')  e ≤loc e' )

Lemma: prior-interface-induction
[Info,T:Type].
  ∀es:EO+(Info). ∀X:EClass(T).
    ∀[P:E(X) ⟶ ℙ]
      ((∀e:E(X). (P[e] supposing ¬↑e ∈b prior(X) ∧ P[prior(X)(e)]  P[e] supposing ↑e ∈b prior(X)))  (∀e:E(X). P[e]))

Definition: es-prior-val
(X)' ==  λes,e. if e ∈b prior(X) then {X(prior(X)(e))} else {} fi 

Lemma: es-prior-val_wf
[Info,T:Type]. ∀[X:EClass(T)].  ((X)' ∈ EClass(T))

Lemma: primed-class-prior-val
[Info,T:Type]. ∀[X:EClass(T)].  Prior(X) (X)' ∈ EClass(T) supposing Singlevalued(X)

Definition: rec-comb
rec-comb(X;f;init) ==  fix((λrec-comb,es,e. (f loc(e) i.(X es e)) (Prior(rec-comb)?init es e))))

Lemma: rec-comb_wf
[Info:Type]. ∀[n:ℕ]. ∀[A:ℕn ⟶ Type]. ∀[X:i:ℕn ⟶ EClass(A i)]. ∀[T:Type]. ∀[f:Id
                                                                                ⟶ (i:ℕn ⟶ bag(A i))
                                                                                ⟶ bag(T)
                                                                                ⟶ bag(T)]. ∀[init:Id ⟶ bag(T)].
  (rec-comb(X;f;init) ∈ EClass(T))

Lemma: rec-comb_wf2
[Info:Type]. ∀[n,m:ℕ]. ∀[A:{m..n-} ⟶ Type]. ∀[X:i:{m..n-} ⟶ EClass(A i)]. ∀[T:Type]. ∀[f:Id
                                                                                            ⟶ (i:{m..n-} ⟶ bag(A i))
                                                                                            ⟶ bag(T)
                                                                                            ⟶ bag(T)].
[init:Id ⟶ bag(T)].
  (rec-comb(X;f;init) ∈ EClass(T))

Definition: rec-combined-class
f|X,(self)'| ==  fix((λrec-combined-class,es,e. (f i.(X es e)) (Prior(rec-combined-class) es e))))

Lemma: rec-combined-class_wf
[Info:Type]. ∀[n:ℕ]. ∀[A:ℕn ⟶ Type]. ∀[X:i:ℕn ⟶ EClass(A i)]. ∀[T:Type]. ∀[f:(i:ℕn ⟶ bag(A i)) ⟶ bag(T) ⟶ bag(T)].
  (f|X,(self)'| ∈ EClass(T))

Definition: rec-combined-loc-class
f|Loc, X, Prior(self)| ==
  fix((λrec-combined-loc-class,es,e. (f loc(e) i.(X es e)) (Prior(rec-combined-loc-class) es e))))

Lemma: rec-combined-loc-class_wf
[Info:Type]. ∀[n:ℕ]. ∀[A:ℕn ⟶ Type]. ∀[X:i:ℕn ⟶ EClass(A i)]. ∀[T:Type]. ∀[f:Id
                                                                                ⟶ (i:ℕn ⟶ bag(A i))
                                                                                ⟶ bag(T)
                                                                                ⟶ bag(T)].
  (f|Loc, X, Prior(self)| ∈ EClass(T))

Definition: simple-comb2
λx,y.F[x; y]|X;Y| ==  simple-comb(λw.F[w 0; 1];λz.[X; Y][z])

Definition: simple-loc-comb2
simple-loc-comb2(l,a,b.F[l; a; b];X;Y) ==  λl,w. F[l; 0; 1]|Loc; λz.[X; Y][z]|

Definition: simple-loc-comb1
simple-loc-comb1(l,b.F[l; b];X) ==  λl,w. F[l; 0]|Loc; λz.[X][z]|

Definition: simple-comb1
λx.F[x]|X| ==  simple-comb(λw.F[w 0];λz.[X][z])

Lemma: simple-comb1_wf
[Info,A,B:Type]. ∀[F:bag(A) ⟶ bag(B)]. ∀[X:EClass(A)].  x.F[x]|X| ∈ EClass(B))

Definition: simple-comb0
b| ==  simple-comb(λw.b;λz.[][z])

Lemma: simple-comb0_wf
[Info,B:Type]. ∀[b:bag(B)].  (b| | ∈ EClass(B))

Definition: rec-combined-loc-class2
l,x,y,s.F[l; x; y; s]|Loc,X,Y,Prior(self)| ==  λl,w,s. F[l; 0; 1; s]|Loc, λz.[X; Y][z], Prior(self)|

Lemma: rec-combined-loc-class2_wf
[Info,A,B,C:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(C)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
  (l,x,y,s.F[l;x;y;s]|Loc,X,Y,Prior(self)| ∈ EClass(C))

Definition: rec-combined-loc-class1
l,x,s.F[l; x; s]|Loc,X,Prior(self)| ==  λl,w,s. F[l; 0; s]|Loc, λn.X, Prior(self)|

Lemma: rec-combined-loc-class1_wf
[Info,A,B:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B) ⟶ bag(B)]. ∀[X:EClass(A)].
  (l,x,s.F[l;x;s]|Loc,X,Prior(self)| ∈ EClass(B))

Definition: rec-combined-class2
a,b,s.F[a; b; s]|X,Y,Prior(self)| ==  λw,s. F[w 0; 1; s]|λz.[X; Y][z],(self)'|

Definition: rec-combined-class1
x,s.F[x; s]|X, Prior(self)| ==  λw,s. F[w 0; s]|λz.[X][z],(self)'|

Definition: rec-combined-class-0
rec-combined-class-0(b) ==  λw.b|λn.[][n],(self)'|

Lemma: rec-combined-class-0_wf
[Info,A:Type]. ∀[F:bag(A) ⟶ bag(A)].  (rec-combined-class-0(F) ∈ EClass(A))

Definition: rec-combined-class-1
F|X,Prior(self)| ==  λw,s. (F (w 0) s)|λn.[X][n],(self)'|

Lemma: rec-combined-class-1_wf
[Info,A,B:Type]. ∀[F:bag(A) ⟶ bag(B) ⟶ bag(B)]. ∀[X:EClass(A)].  (F|X,Prior(self)| ∈ EClass(B))

Definition: rec-combined-class-2
F|X, Y, Prior(self)| ==  λw,s. (F (w 0) (w 1) s)|λn.[X; Y][n],(self)'|

Lemma: rec-combined-class-2_wf
[Info,A,B,C:Type]. ∀[F:bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(C)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
  (F|X, Y, Prior(self)| ∈ EClass(C))

Definition: rec-combined-class-3
rec-combined-class-3(F;X;Y;Z) ==  λw,s. (F (w 0) (w 1) (w 2) s)|λn.[X; Y; Z][n],(self)'|

Lemma: rec-combined-class-3_wf
[Info,A,B,C,D:Type]. ∀[F:bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(D) ⟶ bag(D)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
[Z:EClass(C)].
  (rec-combined-class-3(F;X;Y;Z) ∈ EClass(D))

Definition: rec-combined-class-opt-1
F|X,Prior(self)?init| ==  rec-comb(λn.[X][n];λi,w,s. (F (w 0) s);init)

Lemma: rec-combined-class-opt-1_wf
[Info,A,B:Type]. ∀[F:bag(A) ⟶ bag(B) ⟶ bag(B)]. ∀[X:EClass(A)]. ∀[init:Id ⟶ bag(B)].
  (F|X,Prior(self)?init| ∈ EClass(B))

Definition: rec-combined-loc-class-opt-1
F|Loc, X, Prior(self)?init| ==  rec-comb(λn.[X][n];λi,w,s. (F (w 0) s);init)

Lemma: rec-combined-loc-class-opt-1_wf
[Info,A,B:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B) ⟶ bag(B)]. ∀[X:EClass(A)]. ∀[init:Id ⟶ bag(B)].
  (F|Loc, X, Prior(self)?init| ∈ EClass(B))

Definition: rec-combined-loc-class-0
rec-combined-loc-class-0(F) ==  λl,w. (F l)|Loc, λn.[][n], Prior(self)|

Lemma: rec-combined-loc-class-0_wf
[Info,A:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(A)].  (rec-combined-loc-class-0(F) ∈ EClass(A))

Definition: rec-combined-loc-class-1
rec-combined-loc-class-1(F;X) ==  λl,w,s. (F (w 0) s)|Loc, λn.X, Prior(self)|

Lemma: rec-combined-loc-class-1_wf
[Info,A,B:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B) ⟶ bag(B)]. ∀[X:EClass(A)].  (rec-combined-loc-class-1(F;X) ∈ EClass(B))

Definition: rec-combined-loc-class-2
F|Loc, X, Y, Prior(self)| ==  λl,w,s. (F (w 0) (w 1) s)|Loc, λn.[X; Y][n], Prior(self)|

Lemma: rec-combined-loc-class-2_wf
[Info,A,B,C:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(C)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
  (F|Loc, X, Y, Prior(self)| ∈ EClass(C))

Definition: rec-combined-loc-class-3
rec-combined-loc-class-3(F;X;Y;Z) ==  λl,w,s. (F (w 0) (w 1) (w 2) s)|Loc, λn.[X; Y; Z][n], Prior(self)|

Lemma: rec-combined-loc-class-3_wf
[Info,A,B,C,D:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(D) ⟶ bag(D)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
[Z:EClass(C)].
  (rec-combined-loc-class-3(F;X;Y;Z) ∈ EClass(D))

Definition: rec-combined-class-opt-2
F|X, Y, Prior(self)?init| ==  rec-comb(λn.[X; Y][n];λi,w,s. (F (w 0) (w 1) s);init)

Lemma: rec-combined-class-opt-2_wf
[Info,A,B,C:Type]. ∀[F:bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(C)]. ∀[init:Id ⟶ bag(C)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
  (F|X, Y, Prior(self)?init| ∈ EClass(C))

Definition: rec-combined-class-opt-3
rec-combined-class-opt-3(F;init;X;Y;Z) ==  rec-comb(λn.[X; Y; Z][n];λi,w,s. (F (w 0) (w 1) (w 2) s);init)

Lemma: rec-combined-class-opt-3_wf
[Info,A,B,C,D:Type]. ∀[F:bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(D) ⟶ bag(D)]. ∀[init:Id ⟶ bag(D)]. ∀[X:EClass(A)].
[Y:EClass(B)]. ∀[Z:EClass(C)].
  (rec-combined-class-opt-3(F;init;X;Y;Z) ∈ EClass(D))

Definition: rec-combined-loc-class-opt-2
F|Loc, X, Y, Prior(self)?;init| ==  rec-comb(λn.[X; Y][n];λi,w,s. (F (w 0) (w 1) s);init)

Lemma: rec-combined-loc-class-opt-2_wf
[Info,A,B,C:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(C)]. ∀[init:Id ⟶ bag(C)]. ∀[X:EClass(A)].
[Y:EClass(B)].
  (F|Loc, X, Y, Prior(self)?;init| ∈ EClass(C))

Definition: rec-combined-loc-class-opt-3
rec-combined-loc-class-opt-3(F;init;X;Y;Z) ==  rec-comb(λn.[X; Y; Z][n];λi,w,s. (F (w 0) (w 1) (w 2) s);init)

Lemma: rec-combined-loc-class-opt-3_wf
[Info,A,B,C,D:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(D) ⟶ bag(D)]. ∀[init:Id ⟶ bag(D)]. ∀[X:EClass(A)].
[Y:EClass(B)]. ∀[Z:EClass(C)].
  (rec-combined-loc-class-opt-3(F;init;X;Y;Z) ∈ EClass(D))

Lemma: simple-loc-comb2_wf
[Info,A,B,C:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B) ⟶ bag(C)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
  (simple-loc-comb2(l,a,b.F[l;a;b];X;Y) ∈ EClass(C))

Lemma: simple-loc-comb1_wf
[Info,A,B:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B)]. ∀[X:EClass(A)].  (simple-loc-comb1(l,w.F[l;w];X) ∈ EClass(B))

Lemma: simple-comb2_wf
[Info,A,B,C:Type].  ∀F:bag(A) ⟶ bag(B) ⟶ bag(C). ∀[X:EClass(A)]. ∀[Y:EClass(B)].  x,y.F[x;y]|X;Y| ∈ EClass(C))

Definition: simple-comb3
simple-comb3(x,y,z.F[x; y; z];X;Y;Z) ==  simple-comb(λw.F[w 0; 1; 2];λn.[X; Y; Z][n])

Lemma: simple-comb3_wf
[Info,A,B,C,D:Type].
  ∀F:bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(D)
    ∀[X:EClass(A)]. ∀[Y:EClass(B)]. ∀[Z:EClass(C)].  (simple-comb3(x,y,z.F[x;y;z];X;Y;Z) ∈ EClass(D))

Lemma: rec-combined-class2_wf
[Info,A,B,C:Type]. ∀[F:bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(C)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].
  (x,y,s.F[x;y;s]|X,Y,Prior(self)| ∈ EClass(C))

Lemma: rec-combined-class1_wf
[Info,A,B:Type]. ∀[F:bag(A) ⟶ bag(B) ⟶ bag(B)]. ∀[X:EClass(A)].  (x,s.F[x;s]|X, Prior(self)| ∈ EClass(B))

Definition: simple-loc-comb-2
(Loc,X, Y) ==  λl,w. (F (w 0) (w 1))|Loc; λn.[X; Y][n]|

Definition: simple-loc-comb-3
F|Loc, X, Y, Z| ==  λl,w. (F (w 0) (w 1) (w 2))|Loc; λn.[X; Y; Z][n]|

Definition: simple-loc-comb-1
F(Loc, X) ==  λl,w. (F (w 0))|Loc; λn.[X][n]|

Definition: simple-loc-comb-0
simple-loc-comb-0(b) ==  λl,w. (b l)|Loc; λn.[][n]|

Definition: simple-comb-2
F|X, Y| ==  simple-comb(λw.(F (w 0) (w 1));λn.[X; Y][n])

Definition: simple-comb-3
F|X, Y, Y| ==  simple-comb(λw.(F (w 0) (w 1) (w 2));λn.[X; Y; Z][n])

Definition: simple-comb-1
F|X| ==  simple-comb(λw.(F (w 0));λn.[X][n])

Definition: simple-comb-0
simple-comb-0(b) ==  simple-comb(λw.b;λn.[][n])

Lemma: simple-loc-comb-2_wf
[Info,A,B,C:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B) ⟶ bag(C)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)].  (F (Loc,X, Y) ∈ EClass(C))

Lemma: simple-loc-comb-3_wf
[Info,A,B,C,D:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(D)]. ∀[X:EClass(A)]. ∀[Y:EClass(B)]. ∀[Z:EClass(C)].
  (F|Loc, X, Y, Z| ∈ EClass(D))

Lemma: simple-loc-comb-1_wf
[Info,A,B:Type]. ∀[F:Id ⟶ bag(A) ⟶ bag(B)]. ∀[X:EClass(A)].  (F(Loc, X) ∈ EClass(B))

Lemma: simple-loc-comb-0_wf
[Info,B:Type]. ∀[b:Id ⟶ bag(B)].  (simple-loc-comb-0(b) ∈ EClass(B))

Lemma: send-once-loc-class-eq-once-simple-loc-comb-0
[Info,A:Type]. ∀[b:Id ⟶ bag(A)].  (send-once-loc-class(b) (simple-loc-comb-0(b) once) ∈ EClass(A))

Lemma: simple-comb-2_wf
[Info,A,B,C:Type].  ∀F:bag(A) ⟶ bag(B) ⟶ bag(C). ∀[X:EClass(A)]. ∀[Y:EClass(B)].  (F|X, Y| ∈ EClass(C))

Lemma: simple-comb-3_wf
[Info,A,B,C,D:Type].
  ∀F:bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(D). ∀[X:EClass(A)]. ∀[Y:EClass(B)]. ∀[Z:EClass(C)].  (F|X, Y, Y| ∈ EClass(D))

Lemma: simple-comb-1_wf
[Info,A,B:Type].  ∀F:bag(A) ⟶ bag(B). ∀[X:EClass(A)]. (F|X| ∈ EClass(B))

Lemma: simple-comb-0_wf
[Info,B:Type]. ∀[b:bag(B)].  (simple-comb-0(b) ∈ EClass(B))

Definition: simple-comb-4
simple-comb-4(F;W;X;Y;Z) ==  simple-comb(λw.(F (w 0) (w 1) (w 2) (w 3));λn.[W; X; Y; Z][n])

Lemma: simple-comb-4_wf
[Info,A,B,C,D,E:Type].
  ∀F:bag(A) ⟶ bag(B) ⟶ bag(C) ⟶ bag(D) ⟶ bag(E)
    ∀[W:EClass(A)]. ∀[X:EClass(B)]. ∀[Y:EClass(C)]. ∀[Z:EClass(D)].  (simple-comb-4(F;W;X;Y;Z) ∈ EClass(E))

Definition: simple-loc-comb-4
simple-loc-comb-4(F;W;X;Y;Z) ==  λl,w. (F (w 0) (w <