Theory ClosureHeap

Up to index of Isabelle/HOL/CoreSafe

theory ClosureHeap
imports SafeRASemantics
begin

(*  Title:      Closure Heap
    Author:     Javier de Dios and Ricardo Peņa
    Copyright:  June 2008, Universidad Complutense de Madrid
*)

header {* Closure Heap *}


theory ClosureHeap
imports SafeHeap "../CoreSafe/SafeRASemantics"
begin


(* Closure Definitions *)

inductive_set
  closureL :: "Location => Heap => Location set"
  for p :: Location and h :: Heap
where
  closureL_basic: "p ∈ closureL p h"
| closureL_step:  " [|q ∈ closureL p h; d ∈ descendants q h|] ==> d ∈ closureL p h"

constdefs closure :: "Environment => string => Heap => Location set"
"closure E x h ≡ (case ((fst E) x) of Some (Loc p) => closureL p h
                                    | _ => {})"

constdefs closureV :: "Val => Heap => Location set"
"closureV v h ≡  (case v of IntT i => {}
                         | BoolT b => {}
                         | Loc p => closureL p h)"


constdefs closureLS :: "Environment => string set => Heap => Location set"
"closureLS E L h ≡ (\<Union>x∈L. closure E x h)"

constdefs identityClosure :: "Environment => string => Heap => Heap => bool"
"identityClosure E x h hh ≡ closure E x h = closure E x hh ∧
                            (∀p ∈ closure E x h. (fst h) p = (fst hh) p)"

constdefs identityClosureL :: "Location => Heap => Heap => bool"
"identityClosureL q h hh ≡ closureL q h = closureL q hh ∧
                            (∀p ∈ closureL q h. (fst h) p = (fst hh) p)"


defs def_copy:
 "def_copy p h == (∀ q ∈ closureL p h. q ∈ dom (fst h))"

(* Scope Definition *)
constdefs scope :: "Environment => Heap => Location set"
"scope E h ≡ closureLS E (dom (fst E)) h"

constdefs live :: "Environment => string set => Heap => Location set"
"live E L h ≡ closureLS E L h"



(* Closed Definitions *)


constdefs closed :: "Environment => string set => Heap => bool"
"closed E L h ≡ (live E L h) ⊆ domHeap h"

lemma closed_Empty : "closed E {} h"
by (simp add: closed_def add: live_def add: closureLS_def)

lemma closed_monotone: "closed E (L1 ∪ (L2 - {x1})) h ==>  closed E L1 h"
by (simp add: closed_def add: live_def add: closureLS_def)

constdefs closed_f :: "Val => Heap => bool"
"closed_f v h ≡ (case v of IntT i => True
                         | BoolT b => True
                         | Loc p => closureL p h ⊆ domHeap h)"


(* RecReach Definitions *)

inductive_set
   recReachL :: "Location => Heap => Location set"
   for p :: Location and h :: Heap
where
  recReachL_basic: "p ∈ recReachL p h"
| recReachL_step:  "[| q ∈ recReachL p h; d ∈ recDescendants q h|] ==>  d ∈ recReachL p h"


constdefs recReach :: "Environment => string => Heap => Location set"
"recReach E x h ≡ (case ((fst E) x) of Some (Loc p) => recReachL p h
                                    | _ => {})"


lemma transit_aux: "[| r ∈ closureL d h |] ==>  d ∈ descendants qa h --> r ∈ closureL qa h"
apply (erule closureL.induct)
 apply (rule impI)
 apply (subgoal_tac "qa ∈ closureL qa h")
  apply (erule closureL_step, assumption)
 apply (rule closureL_basic)
apply (rule impI)
apply (drule mp)
 apply assumption
by (erule closureL_step, assumption)

lemma transit_aux2: "[| r ∈  closureL d h;  d ∈ descendants qa h |] ==> r ∈ closureL qa h"
apply (subgoal_tac "[| r ∈ closureL d h |] ==>  d ∈ descendants qa h --> r ∈ closureL qa h", simp)
by (rule transit_aux,assumption)

lemma transit: "[|p ∈ closureL q h|] ==> ∀r. r ∈ closureL p h
                --> r ∈ closureL q h"
apply (erule closureL.induct)
 apply simp
apply clarsimp
apply(erule allE, erule mp)
apply (erule thin_rl)
by (erule transit_aux2,assumption)

lemma closureL_transit: "[|p ∈ closureL q h; r ∈ closureL p h|] ==>  r ∈ closureL q h"
by (frule transit,simp)


lemma closure_transit:  "[|p ∈ closure E x h; q ∈ closureL p h|] ==> q ∈ closure E x h"
apply (simp add: closure_def)
apply (case_tac "fst E x")
 apply simp
apply simp
apply (case_tac "a")
 apply simp_all
apply (erule closureL_transit)
by assumption

lemma closureL_monotone: "p ∈ closureL q (h1', h2') ==>  closureL p (h1', h2') ⊆  closureL q (h1', h2')"
apply (erule closureL.induct)
 apply simp
apply (subgoal_tac "closureL d (h1', h2') ⊆  closureL qa (h1', h2')")
 apply blast
apply (rule subsetI, rule transit_aux2)
 apply simp
by simp

lemma closure_recReach_monotone: 
  "[| p ∈ closure (E1(x1 \<mapsto> r), E2) y (h1', h2');
     closureL p (h1', h2') ∩ recReach (E1(x1 \<mapsto> r), E2) x (h1', h2') ≠ {} |] 
    ==>  closure (E1(x1 \<mapsto> r), E2) y (h1', h2') ∩ recReach (E1(x1 \<mapsto> r), E2) x (h1', h2') ≠ {}"
apply (case_tac "y≠x1")
 apply (simp add: closure_def)
 apply (case_tac "E1 y")
  apply simp
 apply simp
 apply (case_tac "a", simp_all,clarsimp)
 apply (subgoal_tac " p ∈ closureL nat (h1', h2') ==>  closureL p (h1', h2') ⊆  closureL nat (h1', h2')")
  apply blast
 apply (erule closureL_monotone)
apply (simp add: closure_def)
apply (case_tac "r",simp_all,clarsimp)
apply (subgoal_tac " p ∈ closureL nat (h1', h2') ==>  closureL p (h1', h2') ⊆  closureL nat (h1', h2')")
 apply blast
by (erule closureL_monotone)

lemma closure_monotone: "[|y ≠ x1;p ∈ closure (E1(x1 \<mapsto> r), E2) y (h1', h2')|]
        ==>  closureL p (h1', h2') ⊆ closure (E1(x1 \<mapsto> r), E2) y (h1', h2')"
apply (simp add: closure_def)
apply (case_tac "E1 y",simp_all)
apply (case_tac "a", simp_all)
by (erule closureL_monotone)

lemma identityClosureL_monotone_h: 
  " [|x ∈ closureL q h|] ==> q ∈ closureL p h --> identityClosureL p h hh --> x ∈ closureL q hh"
apply (erule closureL.induct)
 apply (intro impI, rule closureL_basic)
apply (intro impI)
apply simp
apply (subgoal_tac "d ∈ descendants qa hh")
 apply (erule closureL_step,simp)
apply (simp add: identityClosureL_def)
apply (erule conjE)
apply (erule_tac x="qa" in ballE)
apply (subgoal_tac "qa ∈ closureL q h")
 apply (subgoal_tac "d ∈ closureL q h")
  apply (simp add: descendants_def)
 apply (erule closureL_step,simp)
apply simp
apply (subgoal_tac "q ∈ closureL p h")
 prefer 2 apply simp
apply (subgoal_tac "[| qa ∈ closureL q h;  q ∈ closureL p h|]  ==> qa ∈  closureL p h",simp)
by (rule closureL_transit)

lemma identityClosureL_monotone_hh: 
  "[|x ∈ closureL q hh|] ==> q ∈ closureL p h --> identityClosureL p h hh --> x ∈ closureL q h"
apply (erule closureL.induct)
 apply (intro impI, rule closureL_basic)
apply (intro impI)
apply simp
apply (subgoal_tac "d ∈ descendants qa h")
 apply (erule closureL_step,simp)
apply (simp add: identityClosureL_def)
apply (erule conjE)
apply (erule_tac x="qa" in ballE)
apply (subgoal_tac "qa ∈ closureL q hh")
 apply (subgoal_tac "d ∈ closureL q hh")
  apply (simp add: descendants_def)
 apply (erule closureL_step,simp)
apply simp
apply (subgoal_tac "q ∈ closureL p hh")
 prefer 2 apply simp
apply (subgoal_tac "[| qa ∈ closureL q hh;  q ∈ closureL p hh|]  ==> qa ∈  closureL p hh",simp)
by (rule closureL_transit)

lemma identityClosureL_monotone: 
  " [|identityClosureL p h hh; q ∈ closureL p h|] ==> identityClosureL q h hh"
apply (simp (no_asm) add: identityClosureL_def)
apply (rule conjI)
 apply (rule equalityI)
  apply (rule subsetI)
  apply (subgoal_tac "[|x ∈ closureL q h|] ==> q ∈ closureL p h --> identityClosureL p h hh --> x ∈ closureL q hh",simp)
  apply (rule identityClosureL_monotone_h,simp)
 apply (rule subsetI)
 apply (subgoal_tac "[|x ∈ closureL q hh|] ==> q ∈ closureL p h --> identityClosureL p h hh --> x ∈ closureL q h",simp)
 apply (rule identityClosureL_monotone_hh,simp)
apply (simp add: identityClosureL_def)
apply (rule ballI)
apply (erule conjE)
apply (subgoal_tac "q ∈ closureL p h")
 apply (frule_tac r="pa" and h="h" in closureL_transit)
  apply (rule closureL_basic)
 apply (erule_tac x="pa" in ballE,clarsimp)
apply (frule_tac r="pa" and h ="h" and p="q" in closureL_transit,clarsimp) 
 apply simp 
by simp


lemma identityClosure_closureL_monotone:
  "[| identityClosure E x h hh; q ∈ closure E x h|] ==> identityClosureL q h hh"
apply (simp add: identityClosure_def)
apply (simp add: closure_def)
apply (case_tac "fst E x",simp_all)
apply (case_tac "a",simp_all)
apply (subgoal_tac "closureL nat h = closureL nat hh ∧ (∀p∈closureL nat h. fst h p = fst hh p) --> identityClosureL nat h hh",simp)
 apply (erule identityClosureL_monotone,simp)
by (simp add: identityClosureL_def)

lemma recReachL_subseteq_closureL: 
  "recReachL p h ⊆ closureL p h"
apply clarify
apply (erule recReachL.induct)
apply (simp add: closure_def)
apply (rule closureL_basic)
apply (simp add: closure_def)
apply (subgoal_tac "recDescendants q h ⊆ descendants q h")
apply (erule closureL_step, blast)
apply (simp add: recDescendants_def add: descendants_def)
apply (case_tac "fst h q", simp, simp)
apply (subgoal_tac "getRecursiveValuesCell (snd a) ⊆ getNonBasicValuesCell (snd a)", simp)
apply (simp add: getRecursiveValuesCell_def add: getNonBasicValuesCell_def)
apply (simp add: isRecursive_def add: isNonBasicValue_def)
apply auto
done


lemma recReach_subseteq_closure: 
  "recReach E z h ⊆ closure E z h"
apply (simp add: recReach_def)
apply (case_tac "fst E z",simp_all)
apply (case_tac "a",simp_all)
apply (simp add: closure_def)
by (rule recReachL_subseteq_closureL)

lemma identityClosure_equals_recReach_hh: 
  "p∈ recReachL q hh ==> closureL q h = closureL q hh --> (∀p ∈ closureL q h. (fst h) p = (fst hh) p) --> p ∈ recReachL q h"
apply (erule recReachL.induct)
 apply (intro impI)
 apply (rule recReachL_basic)
apply clarsimp
apply (erule_tac c="qa" in equalityCE)
 apply (subgoal_tac " d ∈ recDescendants qa hh ==>  d ∈ recDescendants qa h",simp)
  apply (erule recReachL_step,simp)
 apply (simp add: recDescendants_def)
apply (subgoal_tac " recReachL q h ⊆  closureL q h")
 apply blast
by (rule recReachL_subseteq_closureL) 

lemma identityClosure_equals_recReach_h: 
  "p∈ recReachL q h ==> closureL q h = closureL q hh --> (∀p ∈ closureL q h. (fst h) p = (fst hh) p) --> p ∈ recReachL q hh"
apply (erule recReachL.induct)
 apply (intro impI)
 apply (rule recReachL_basic)
apply clarsimp
apply (erule_tac c="qa" in equalityCE)
 apply (subgoal_tac " d ∈ recDescendants qa h ==>  d ∈ recDescendants qa hh",simp)
  apply (erule recReachL_step,simp)
 apply (simp add: recDescendants_def)
apply (subgoal_tac " recReachL q hh ⊆  closureL q hh")
 apply blast
by (rule recReachL_subseteq_closureL) 


lemma identityClosure_equals_recReach: 
  "identityClosure E x h hh ==> recReach E x h = recReach E x hh"
apply (simp add: identityClosure_def)
apply (simp add: closure_def)
apply (case_tac "fst E x",simp_all)
apply (simp add: recReach_def)
apply (case_tac "a",simp_all)
apply (elim conjE)
apply (simp_all add: recReach_def)
apply (rule equalityI)
 apply (rule subsetI)
 apply (subgoal_tac "xa∈ recReachL nat h ==> 
                     closureL nat h = closureL nat hh --> (∀p ∈ closureL nat h. (fst h) p = (fst hh) p) --> xa ∈ recReachL nat hh",simp)
 apply (rule identityClosure_equals_recReach_h,simp)
apply (rule subsetI)
apply (subgoal_tac "xa∈ recReachL nat hh ==> 
                    closureL nat h = closureL nat hh --> (∀p ∈ closureL nat h. (fst h) p = (fst hh) p) --> xa ∈ recReachL nat h",simp)
by (rule identityClosure_equals_recReach_hh,simp)

(************************* CASE ********************)

lemma closure_monotone_extend: 
  "[| ∀i<length alts. set (snd (extractP (fst (alts ! i)))) ∩ dom E = {}  ∧ 
                     length (snd (extractP (fst (alts ! i)))) = length vs; 
     x∈ dom E; 
    length alts > 0;
    i < length alts |] 
  ==> closure (E, E') x (h, k) =  closure (extend E (snd (extractP (fst (alts ! i))))  vs, E') x (h, k)"
apply (erule_tac x="i" in allE)
apply (subgoal_tac " x ∉ set (snd (extractP (fst (alts ! i))))")
 apply (subgoal_tac 
   "E x = extend E  (snd (extractP (fst (alts ! i)))) vs x")
  apply (simp add:closure_def)
 apply (rule extend_monotone_i) 
 apply (simp,simp,simp)
by blast


lemma closure_monotone_extend_2: 
  "[| set (snd (extractP (fst (alts ! i)))) ∩ dom E = {};
     length (snd (extractP (fst (alts ! i)))) = length vs; 
     x∈ dom E; 
    length alts > 0;
    i < length alts |] 
  ==> closure (E, E') x (h, k) =  closure (extend E (snd (extractP (fst (alts ! i))))  vs, E') x (h, k)"
apply (subgoal_tac " x ∉ set (snd (extractP (fst (alts ! i))))")
 apply (subgoal_tac 
   "E x = extend E  (snd (extractP (fst (alts ! i)))) vs x")
  apply (simp add:closure_def)
 apply (rule extend_monotone_i) 
 apply (simp,simp,simp)
by blast

lemma closure_monotone_extend_3: 
  "[| set (snd (extractP (fst (alts ! i)))) ∩ dom E = {};
     length (snd (extractP (fst (alts ! i)))) = length vs; 
     x∈ dom E; 
    length alts > 0;
    i < length alts;
    xa ∈ closure (extend E (snd (extractP (fst (alts ! i))))  vs, E') x (h, k) |] 
  ==> xa ∈ closure (E, E') x (h, k)"
apply (subgoal_tac " x ∉ set (snd (extractP (fst (alts ! i))))")
 apply (subgoal_tac 
   "E x = extend E  (snd (extractP (fst (alts ! i)))) vs x")
  apply (simp add:closure_def)
 apply (rule extend_monotone_i) 
 apply (simp,simp,simp)
by blast

lemma recReach_monotone_extend: 
  "[| ∀i<length alts. set (snd (extractP (fst (alts ! i)))) ∩ dom E = {} ∧ 
                     length (snd (extractP (fst (alts ! i)))) = length vs;
    x ∈ dom E;
    length alts > 0; i < length alts|] 
  ==> recReach (E, E') x (h, k) =  recReach (extend E (snd (extractP (fst (alts ! i))))  vs, E') x (h, k)"
apply (erule_tac x="i" in allE)
apply (subgoal_tac " x ∉ set (snd (extractP (fst (alts ! i))))")
 apply (subgoal_tac 
   "E x = extend E  (snd (extractP (fst (alts ! i)))) vs x")
  apply (simp add:recReach_def)
 apply (rule extend_monotone_i) 
 apply (simp,simp,simp)
by blast

lemma recReach_monotone_extend_2: 
  "[| set (snd (extractP (fst (alts ! i)))) ∩ dom E = {};
    length (snd (extractP (fst (alts ! i)))) = length vs;
    x ∈ dom E;
    length alts > 0; i < length alts|] 
  ==> recReach (E, E') x (h, k) =  recReach (extend E (snd (extractP (fst (alts ! i))))  vs, E') x (h, k)"
apply (subgoal_tac " x ∉ set (snd (extractP (fst (alts ! i))))")
 apply (subgoal_tac 
   "E x = extend E  (snd (extractP (fst (alts ! i)))) vs x")
  apply (simp add:recReach_def)
 apply (rule extend_monotone_i) 
 apply (simp,simp,simp)
by blast



lemma monotone_extend_closures:
"[|∀ i < length assert. fst (assert ! i) ⊆ dom (snd (assert ! i));
  ∀ i < length alts. set (snd (extractP (fst (alts ! i)))) ∩ dom E1  = {} ∧ 
                     length (snd (extractP (fst (alts ! i)))) = length vs;
  ∀ i < length assert. dom (snd (assert ! i)) ⊆ dom (extend E1 (snd (extractP (fst (alts ! i)))) vs);
   z∈fst (assert ! i); z ∉ set (snd (extractP (fst (alts ! i))));
   length alts = length assert;
   closure (E1, E2) x (h, k) ∩ recReach (E1, E2) z (h, k) ≠ {};
   x∈ dom E1; 
   length assert > 0;
   i < length alts |] 
 ==>
  closure (extend E1 (snd (extractP (fst (alts ! i)))) vs, E2) x (h, k) ∩
  recReach (extend E1 (snd (extractP (fst (alts ! i)))) vs, E2) z (h, k) ≠ {}"
apply (subgoal_tac "closure (E1, E2) x (h, k) = 
                    closure (extend E1 (snd (extractP (fst (alts ! i)))) vs, E2) x (h, k)")
 prefer 2 apply (simp,rule closure_monotone_extend,simp,simp,simp,simp)
apply (subgoal_tac "z ∈ dom E1")
 apply (subgoal_tac "recReach (E1, E2) z (h, k) = 
                     recReach (extend E1 (snd (extractP (fst (alts ! i)))) vs, E2) z (h, k)")
 prefer 2 apply (rule recReach_monotone_extend,assumption+,simp,simp)
 apply (erule_tac x="i" in allE,simp)
apply (erule_tac x="i" in allE,simp)
apply (erule_tac x="i" in allE,simp)
apply (erule_tac x="i" in allE,simp)
apply (subgoal_tac "z ∈ dom (extend E1 (snd (extractP (fst (alts ! i)))) vs)")
 prefer 2 apply blast
apply (elim conjE)
by (rule extend_prop1,assumption+)


lemma monotone_extend_closures_i:
"[| set (snd (extractP (fst (alts ! i)))) ∩ dom E1  = {} ∧ length (snd (extractP (fst (alts ! i)))) = length vs;
   fst (assert ! i) ⊆ dom (snd (assert ! i));
   z∈fst (assert ! i);  z ∉ set (snd (extractP (fst (alts ! i))));
   length alts = length assert;
   length alts > 0;
   closure (E1, E2) x (h, k) ∩ recReach (E1, E2) z (h, k) ≠ {};
   dom (snd (assert ! i)) ⊆ dom (extend E1 (snd (extractP (fst (alts ! i)))) vs);
   x∈ dom E1; 
   i < length alts |] 
 ==>
  closure (extend E1 (snd (extractP (fst (alts ! i)))) vs, E2) x (h, k) ∩
  recReach (extend E1 (snd (extractP (fst (alts ! i)))) vs, E2) z (h, k) ≠ {}"
apply (elim conjE)
apply (subgoal_tac "closure (E1, E2) x (h, k) = 
                    closure (extend E1 (snd (extractP (fst (alts ! i)))) vs, E2) x (h, k)")
 prefer 2 apply (simp, rule closure_monotone_extend_2,simp,assumption+,simp,simp)    
apply (subgoal_tac "z ∈ dom E1")
apply (subgoal_tac "recReach (E1, E2) z (h, k) = 
                    recReach (extend E1 (snd (extractP (fst (alts ! i)))) vs, E2) z (h, k)")
 prefer 2 apply (rule recReach_monotone_extend_2,simp,assumption+,simp) 
apply (subgoal_tac "z ∈ dom (extend E1 (snd (extractP (fst (alts ! i)))) vs)")
 prefer 2 apply blast
by (rule extend_prop1,assumption+)

end

lemma closed_Empty:

  closed E {} h

lemma closed_monotone:

  closed E (L1.0 ∪ (L2.0 - {x1.0})) h ==> closed E L1.0 h

lemma transit_aux:

  rclosureL d h ==> d ∈ descendants qa h --> rclosureL qa h

lemma transit_aux2:

  [| rclosureL d h; d ∈ descendants qa h |] ==> rclosureL qa h

lemma transit:

  pclosureL q h ==> ∀r. rclosureL p h --> rclosureL q h

lemma closureL_transit:

  [| pclosureL q h; rclosureL p h |] ==> rclosureL q h

lemma closure_transit:

  [| p ∈ closure E x h; qclosureL p h |] ==> q ∈ closure E x h

lemma closureL_monotone:

  pclosureL q (h1', h2') ==> closureL p (h1', h2')  closureL q (h1', h2')

lemma closure_recReach_monotone:

  [| p ∈ closure (E1.0(x1.0 |-> r), E2.0) y (h1', h2');
     closureL p (h1', h2') ∩ recReach (E1.0(x1.0 |-> r), E2.0) x (h1', h2') 
     {} |]
  ==> closure (E1.0(x1.0 |-> r), E2.0) y (h1', h2') ∩
      recReach (E1.0(x1.0 |-> r), E2.0) x (h1', h2') 
      {}

lemma closure_monotone:

  [| y  x1.0; p ∈ closure (E1.0(x1.0 |-> r), E2.0) y (h1', h2') |]
  ==> closureL p (h1', h2')  closure (E1.0(x1.0 |-> r), E2.0) y (h1', h2')

lemma identityClosureL_monotone_h:

  xclosureL q h
  ==> qclosureL p h --> identityClosureL p h hh --> xclosureL q hh

lemma identityClosureL_monotone_hh:

  xclosureL q hh
  ==> qclosureL p h --> identityClosureL p h hh --> xclosureL q h

lemma identityClosureL_monotone:

  [| identityClosureL p h hh; qclosureL p h |] ==> identityClosureL q h hh

lemma identityClosure_closureL_monotone:

  [| identityClosure E x h hh; q ∈ closure E x h |] ==> identityClosureL q h hh

lemma recReachL_subseteq_closureL:

  recReachL p h  closureL p h

lemma recReach_subseteq_closure:

  recReach E z h  closure E z h

lemma identityClosure_equals_recReach_hh:

  precReachL q hh
  ==> closureL q h = closureL q hh -->
      (∀pclosureL q h. fst h p = fst hh p) --> precReachL q h

lemma identityClosure_equals_recReach_h:

  precReachL q h
  ==> closureL q h = closureL q hh -->
      (∀pclosureL q h. fst h p = fst hh p) --> precReachL q hh

lemma identityClosure_equals_recReach:

  identityClosure E x h hh ==> recReach E x h = recReach E x hh

lemma closure_monotone_extend:

  [| ∀i<length alts.
        set (snd (extractP (fst (alts ! i)))) ∩ dom E = {} ∧
        length (snd (extractP (fst (alts ! i)))) = length vs;
     xdom E; 0 < length alts; i < length alts |]
  ==> closure (E, E') x (h, k) =
      closure (extend E (snd (extractP (fst (alts ! i)))) vs, E') x (h, k)

lemma closure_monotone_extend_2:

  [| set (snd (extractP (fst (alts ! i)))) ∩ dom E = {};
     length (snd (extractP (fst (alts ! i)))) = length vs; xdom E;
     0 < length alts; i < length alts |]
  ==> closure (E, E') x (h, k) =
      closure (extend E (snd (extractP (fst (alts ! i)))) vs, E') x (h, k)

lemma closure_monotone_extend_3:

  [| set (snd (extractP (fst (alts ! i)))) ∩ dom E = {};
     length (snd (extractP (fst (alts ! i)))) = length vs; xdom E;
     0 < length alts; i < length alts;
     xa ∈ closure (extend E (snd (extractP (fst (alts ! i)))) vs, E') x (h, k) |]
  ==> xa ∈ closure (E, E') x (h, k)

lemma recReach_monotone_extend:

  [| ∀i<length alts.
        set (snd (extractP (fst (alts ! i)))) ∩ dom E = {} ∧
        length (snd (extractP (fst (alts ! i)))) = length vs;
     xdom E; 0 < length alts; i < length alts |]
  ==> recReach (E, E') x (h, k) =
      recReach (extend E (snd (extractP (fst (alts ! i)))) vs, E') x (h, k)

lemma recReach_monotone_extend_2:

  [| set (snd (extractP (fst (alts ! i)))) ∩ dom E = {};
     length (snd (extractP (fst (alts ! i)))) = length vs; xdom E;
     0 < length alts; i < length alts |]
  ==> recReach (E, E') x (h, k) =
      recReach (extend E (snd (extractP (fst (alts ! i)))) vs, E') x (h, k)

lemma monotone_extend_closures:

  [| ∀i<length assert. fst (assert ! i)  dom (snd (assert ! i));
     ∀i<length alts.
        set (snd (extractP (fst (alts ! i)))) ∩ dom E1.0 = {} ∧
        length (snd (extractP (fst (alts ! i)))) = length vs;
     ∀i<length assert.
        dom (snd (assert ! i))
         dom (extend E1.0 (snd (extractP (fst (alts ! i)))) vs);
     z ∈ fst (assert ! i); z  set (snd (extractP (fst (alts ! i))));
     length alts = length assert;
     closure (E1.0, E2.0) x (h, k) ∩ recReach (E1.0, E2.0) z (h, k)  {};
     xdom E1.0; 0 < length assert; i < length alts |]
  ==> closure (extend E1.0 (snd (extractP (fst (alts ! i)))) vs, E2.0) x (h, k) ∩
      recReach (extend E1.0 (snd (extractP (fst (alts ! i)))) vs, E2.0) z (h, k) 
      {}

lemma monotone_extend_closures_i:

  [| set (snd (extractP (fst (alts ! i)))) ∩ dom E1.0 = {} ∧
     length (snd (extractP (fst (alts ! i)))) = length vs;
     fst (assert ! i)  dom (snd (assert ! i)); z ∈ fst (assert ! i);
     z  set (snd (extractP (fst (alts ! i)))); length alts = length assert;
     0 < length alts;
     closure (E1.0, E2.0) x (h, k) ∩ recReach (E1.0, E2.0) z (h, k)  {};
     dom (snd (assert ! i))
      dom (extend E1.0 (snd (extractP (fst (alts ! i)))) vs);
     xdom E1.0; i < length alts |]
  ==> closure (extend E1.0 (snd (extractP (fst (alts ! i)))) vs, E2.0) x (h, k) ∩
      recReach (extend E1.0 (snd (extractP (fst (alts ! i)))) vs, E2.0) z (h, k) 
      {}