(** *** Lemmas about invariants preserved by coresteps*)

(* Specifications: *)
(** [mem_compatible] is preserved by coresteps*)
Lemma decay_compatible:
forall (tp : t)  (m m' : mem) i
(pf : containsThread tp i) (c': semC)
(Hinv: invariant tp)
(Hcompatible : mem_compatible tp m)
(Hdecay: decay (restrPermMap (DryHybridMachine.compat_th _ _ Hcompatible pf).1) m')
(Hvalid_blocks: forall b, Mem.valid_block m b -> Mem.valid_block m' b),
mem_compatible (updThread pf (Krun c') (getCurPerm m', (getThreadR pf).2)) m'.
(** [mem_compatible] is preserved by coresteps*)
Lemma corestep_compatible:
forall (tp : t)  (m m' : mem) i ev
(pf : containsThread tp i) (c c': semC)
(Hinv: invariant tp)
(Hcode: getThreadC pf = Krun c)
(Hcompatible : mem_compatible tp m)
(Hcorestep: ev_step semSem c (restrPermMap (DryHybridMachine.compat_th _ _ Hcompatible pf).1) ev c' m'),
mem_compatible (updThread pf (Krun c') (getCurPerm m', (getThreadR pf).2)) m'.
(** [mem_compatible] is preserved by [initial_core]*)
Lemma initial_core_compatible:
forall (tp : t)  (m m' : mem) i n vf arg
(pf : containsThread tp i) (c: semC)
(Hinv: invariant tp)
(Hcompatible : mem_compatible tp m)
(Hinitial: initial_core semSem n (restrPermMap (DryHybridMachine.compat_th _ _ Hcompatible pf).1) c m' vf arg),
mem_compatible (updThread pf (Krun c) (getCurPerm m', (getThreadR pf).2)) m'.
(** Permission [decay] preserves disjointness*)
Lemma decay_disjoint:
forall m m' p
(Hdecay: decay m m')
(Hlt: permMapLt p (getMaxPerm m))
(Hdisjoint: permMapsDisjoint (getCurPerm m) p),
permMapsDisjoint (getCurPerm m') p.
(** [permMapCoherence] is preserved by decay *)
Lemma decay_coherence :
forall (m m' : mem) (pmap : access_map)
(Hdecay: decay m m')
(Hlt: permMapLt pmap (getMaxPerm m))
(Hcoh: permMapCoherence (getCurPerm m) pmap),
permMapCoherence (getCurPerm m') pmap.
Lemma decay_invariant:
forall tp m m1 m1' i (pf: containsThread tp i) c
(Hinv : invariant tp)
(Hcompatible : mem_compatible tp m)
(Hrestrict_pmap : restrPermMap (Hcompatible i pf)#1 = m1)
(Hdecay: decay m1 m1'),
invariant (updThread pf (Krun c) (getCurPerm m1', (getThreadR pf)#2)).
(** [invariant] is preserved by a corestep *)
Lemma initial_core_invariant:
forall (tp : t)  (m : mem) (i : nat) n
(pf : containsThread tp i) c m1 m' vf arg
(Hinv: invariant tp)
(Hcompatible: mem_compatible tp m)
(Hrestrict_pmap: restrPermMap (DryHybridMachine.compat_th _ _ Hcompatible pf).1 = m1)
(Hcorestep: initial_core semSem n m1 c m' vf arg),
invariant (updThread pf (Krun c) (getCurPerm m', (getThreadR pf).2)).
(** [invariant] is preserved by a corestep *)
Lemma corestep_invariant:
forall (tp : t)  (m : mem) (i : nat)
(pf : containsThread tp i) c m1 m1' c'
(Hinv: invariant tp)
(Hcompatible: mem_compatible tp m)
(Hrestrict_pmap: restrPermMap (DryHybridMachine.compat_th _ _ Hcompatible pf).1 = m1)
(Hcorestep: corestep semSem c m1 c' m1')
(Hcore: getThreadC pf = Krun c),
invariant (updThread pf (Krun c') (getCurPerm m1', (getThreadR pf).2)).
(** A corestep cannot change the contents of memory locations where permission is not above [Readable]*)
Lemma corestep_stable_val:
forall  c c' m m' pmap1 pmap2
(Hlt1: permMapLt pmap1 (getMaxPerm m))
(Hlt2: permMapLt pmap2 (getMaxPerm m))
(Hdisjoint: permMapsDisjoint pmap1 pmap2 \/ permMapCoherence pmap1 pmap2)
(Hstep: corestep semSem c (restrPermMap Hlt1) c' m'),
forall b ofs (Hreadable: Mem.perm (restrPermMap Hlt2) b ofs Cur Readable),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
(** If some thread has permission above readable on some address then stepping another thread cannot change the value of that location*)
Corollary corestep_disjoint_val:
forall (tp : t)  (m m' : mem) i j (Hneq: i <> j)
(c c' : semC)
(pfi : containsThread tp i) (pfj : containsThread tp j)
(Hcomp : mem_compatible tp m) (b : block) (ofs : Z)
(Hreadable: Mem.perm (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfj).1) b ofs Cur Readable \/
Mem.perm (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfj).2) b ofs Cur Readable)
(Hcorestep: corestep semSem c (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfi).1) c' m')
(Hinv: invariant tp),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
Corollary corestep_disjoint_locks:
forall (tp : t) (m m' : mem) i j (c c' : semC)
(pfi : containsThread tp i) (pfj : containsThread tp j)
(Hcomp : mem_compatible tp m) (b : block) (ofs : Z)
(Hreadable: Mem.perm (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfj).2) b ofs Cur Readable)
(Hcorestep: corestep semSem c (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfi).1) c' m')
(Hinv: invariant tp),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
(** If some lock has permission above [Readable] on some address then stepping a thread cannot change the value of that location*)
Lemma corestep_disjoint_val_lockpool :
forall (tp : t)  (m m' : mem) i (c c' : semC)
(pfi : containsThread tp i) (Hcomp : mem_compatible tp m) addr pmap
(Hlock: lockRes tp addr = Some pmap)
(b : block) (ofs : Z)
(Hreadable: Mem.perm (restrPermMap (DryHybridMachine.compat_lp _ _ Hcomp _ _ Hlock).1)
b ofs Cur Readable \/
Mem.perm (restrPermMap (DryHybridMachine.compat_lp _ _ Hcomp _ _ Hlock).2)
b ofs Cur Readable)
(Hcorestep: corestep semSem c (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfi).1) c' m')
(Hinv: invariant tp),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
Lemma initial_core_stable_val:
forall  n c m m' pmap1 pmap2 v arg
(Hlt1: permMapLt pmap1 (getMaxPerm m))
(Hlt2: permMapLt pmap2 (getMaxPerm m))
(Hdisjoint: permMapsDisjoint pmap1 pmap2 \/ permMapCoherence pmap1 pmap2)
(Hstep: initial_core semSem n (restrPermMap Hlt1) c m' v arg),
forall b ofs (Hreadable: Mem.perm (restrPermMap Hlt2) b ofs Cur Readable),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
Corollary initial_core_disjoint_val:
forall (tp : t)  (m m' : mem) i j (Hneq: i <> j) n v arg
(c c' : semC)
(pfi : containsThread tp i) (pfj : containsThread tp j)
(Hcomp : mem_compatible tp m) (b : block) (ofs : Z)
(Hreadable: Mem.perm (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfj).1) b ofs Cur Readable \/
Mem.perm (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfj).2) b ofs Cur Readable)
(Hcorestep: initial_core semSem n (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfi).1) c m' v arg)
(Hinv: invariant tp),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
Corollary initial_core_disjoint_locks:
forall (tp : t) (m m' : mem) i j (c : semC) n v arg
(pfi : containsThread tp i) (pfj : containsThread tp j)
(Hcomp : mem_compatible tp m) (b : block) (ofs : Z)
(Hreadable: Mem.perm (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfj).2) b ofs Cur Readable)
(Hcorestep: initial_core semSem n (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfi).1) c m' v arg)
(Hinv: invariant tp),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
(** If some lock has permission above [Readable] on some address then stepping a thread cannot change the value of that location*)
Lemma initial_core_disjoint_val_lockpool :
forall (tp : t)  (m m' : mem) i (c c' : semC) n v arg
(pfi : containsThread tp i) (Hcomp : mem_compatible tp m) addr pmap
(Hlock: lockRes tp addr = Some pmap)
(b : block) (ofs : Z)
(Hreadable: Mem.perm (restrPermMap (DryHybridMachine.compat_lp _ _ Hcomp _ _ Hlock).1)
b ofs Cur Readable \/
Mem.perm (restrPermMap (DryHybridMachine.compat_lp _ _ Hcomp _ _ Hlock).2)
b ofs Cur Readable)
(Hcorestep: initial_core semSem n (restrPermMap (DryHybridMachine.compat_th _ _ Hcomp pfi).1) c m' v arg)
(Hinv: invariant tp),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
Lemma permMapLt_decay:
forall pmap m m'
(Hdecay: strong_decay m m')
(Hlt: permMapLt pmap (getMaxPerm m)),
permMapLt pmap (getMaxPerm m').