From Velus Require Import Common.
From Velus Require Import Environment.
From Coq Require Import Setoid Morphisms.
From Coq Require Import List.
Import List.ListNotations.
Set Implicit Arguments.
VelusMemory
Datatype
Definition env :=
Env.t.
Inductive memory (
V:
Type) :=
Mem {
values:
env V;
instances:
env (
memory V)
}.
Operations
Section Operations.
Variable V W:
Type.
Definition empty_memory :
memory V :=
Mem (
Env.empty V) (
Env.empty (
memory V)).
Definition find_val (
x:
ident) (
m:
memory V) :
option V :=
Env.find x (
values m).
Definition find_inst (
x:
ident) (
m:
memory V) :
option (
memory V) :=
Env.find x (
instances m).
Definition add_val (
x:
ident) (
v:
V) (
m:
memory V) :
memory V :=
Mem (
Env.add x v (
values m)) (
instances m).
Definition add_inst (
x:
ident) (
m':
memory V) (
m:
memory V) :
memory V :=
Mem (
values m) (
Env.add x m' (
instances m)).
Fixpoint mmap (
f:
V ->
W) (
m:
memory V) :
memory W :=
Mem (
Env.map f (
values m)) (
Env.map (
mmap f) (
instances m)).
Definition remove_inst (
x:
ident) (
m:
memory V) :
memory V :=
Mem (
values m) (
Env.remove x (
instances m)).
Definition remove_val (
x:
ident) (
m:
memory V) :
memory V :=
Mem (
Env.remove x (
values m)) (
instances m).
End Operations.
Induction Scheme
Section VelusMemoryInd.
Variable V:
Type.
Variable P:
memory V ->
Prop.
Hypothesis MemCase:
forall m,
(
forall m'
x,
find_inst x m =
Some m' ->
P m') ->
P m.
Fixpoint memory_ind' (
m :
memory V):
P m.
Proof.
unfold find_inst in MemCase.
destruct m as [?
xms].
apply MemCase;
simpl.
induction xms;
intros *
Find.
-
rewrite Env.gleaf in Find;
discriminate.
-
destruct x;
simpl in Find.
+
eapply IHxms2;
eauto.
+
eapply IHxms1;
eauto.
+
destruct o.
*
symmetry in Find;
inv Find.
apply memory_ind'.
*
discriminate.
Qed.
End VelusMemoryInd.
Inductive equal_memory {
V:
Type} :
memory V ->
memory V ->
Prop :=
equal_memory_intro:
forall m m',
Env.Equal (
values m) (
values m') ->
Env.Equiv equal_memory (
instances m) (
instances m') ->
equal_memory m m'.
Infix "≋" :=
equal_memory (
at level 70,
no associativity).
Infix "⌈≋⌉" := (
orel equal_memory) (
at level 70,
no associativity).
Section EqualVelusMemory.
Context {
V:
Type}.
Lemma equal_memory_refl:
forall (
m:
memory V),
m ≋
m.
Proof.
induction m as [?
IH]
using memory_ind'.
constructor.
-
reflexivity.
-
split.
+
reflexivity.
+
intros *
Find ?.
eapply Env.Props.P.F.MapsTo_fun in Find;
eauto.
rewrite <-
Find;
eauto.
Qed.
Lemma equal_memory_sym:
forall (
m m':
memory V),
m ≋
m' ->
m' ≋
m.
Proof.
induction m as [? IH] using memory_ind'.
inversion_clear 1 as [?? Vals Insts].
constructor.
- now symmetry.
- destruct Insts as (Insts1 & Insts2); split.
now symmetry; auto.
intros k e1 e2 M1 M2.
eapply Insts2 in M1; eauto.
Qed.
Lemma equal_memory_trans:
forall (
m1 m2 m3:
memory V),
m1 ≋
m2 ->
m2 ≋
m3 ->
m1 ≋
m3.
Proof.
induction m1 as [?
IH]
using memory_ind'.
inversion_clear 1
as [??
Vals12 Insts12];
inversion_clear 1
as [??
Vals23 Insts23].
constructor.
-
now rewrite Vals12.
-
destruct Insts12 as (
In12 &
HMapsTo12).
destruct Insts23 as (?&
HMapsTo23).
split.
+
now setoid_rewrite In12.
+
intros *
Find1 Find3.
assert (
exists e'',
Env.MapsTo k e'' (
instances m2))
as (
e'' &?).
{
setoid_rewrite Env.Props.P.F.find_mapsto_iff.
rewrite <-
Env.In_find, <-
In12,
Env.In_find.
setoid_rewrite <-
Env.Props.P.F.find_mapsto_iff;
eauto.
}
pose proof Find1.
apply (
HMapsTo12 _ _ e'')
in Find1;
auto.
apply (
HMapsTo23 _ e'')
in Find3;
eauto.
Qed.
Add Relation (
memory V)
equal_memory
reflexivity proved by equal_memory_refl
symmetry proved by equal_memory_sym
transitivity proved by equal_memory_trans
as equal_memory_rel.
End EqualVelusMemory.
Existing Instance equal_memory_rel.
Hint Immediate equal_memory_rel_Reflexive.
Hint Immediate equal_memory_rel_Transitive.
Add Parametric Morphism V: (@
values V)
with signature equal_memory ==>
Env.Equal
as values_equal_memory.
Proof.
intros * E x.
inversion_clear E as [?? Vals]; now rewrite Vals.
Qed.
Add Parametric Morphism V: (@
instances V)
with signature equal_memory ==>
Env.Equiv equal_memory
as instances_equal_memory.
Proof.
intros * E.
inversion_clear E as [??? Insts]; auto.
Qed.
Add Parametric Morphism V x: (@
add_inst V x)
with signature equal_memory ==>
equal_memory ==>
equal_memory
as add_inst_equal_memory.
Proof.
intros ? ? E1 ? ? E2.
constructor; simpl; rewrite E2.
+ reflexivity.
+ now rewrite E1.
Qed.
Add Parametric Morphism V x: (@
add_val V x)
with signature eq ==>
equal_memory ==>
equal_memory
as add_val_equal_memory.
Proof.
intros * E.
constructor; simpl; rewrite E; reflexivity.
Qed.
Add Parametric Morphism V x: (@
find_val V x)
with signature equal_memory ==>
eq
as find_val_equal_memory.
Proof.
intros * E.
inversion_clear E as [?? Vals].
apply Vals.
Qed.
Properties
Section Properties.
Variable V:
Type.
Variables (
x y:
ident)
(
v:
V)
(
m m':
memory V).
Lemma find_val_gss:
find_val x (
add_val x v m) =
Some v.
Proof.
Lemma find_val_gso:
x <>
y ->
find_val x (
add_val y v m) =
find_val x m.
Proof.
Lemma find_inst_gss:
find_inst x (
add_inst x m'
m) =
Some m'.
Proof.
Lemma find_inst_gso:
x <>
y ->
find_inst x (
add_inst y m'
m) =
find_inst x m.
Proof.
Lemma find_val_add_inst:
find_val x (
add_inst y m'
m) =
find_val x m.
Proof.
Lemma find_inst_add_val:
find_inst x (
add_val y v m) =
find_inst x m.
Proof.
Lemma find_val_mmap:
forall W (
f:
V ->
W),
find_val x (
mmap f m) =
option_map f (
find_val x m).
Proof.
Lemma find_inst_mmap:
forall W (
f:
V ->
W),
find_inst x (
mmap f m) =
option_map (
mmap f) (
find_inst x m).
Proof.
Lemma add_remove_inst_same:
find_inst x m =
Some m' ->
m ≋
add_inst x m' (
remove_inst x m).
Proof.
Lemma find_inst_grs:
find_inst x (
remove_inst x m) =
None.
Proof.
Lemma find_inst_gro:
x <>
y ->
find_inst x (
remove_inst y m) =
find_inst x m.
Proof.
Lemma add_remove_val_same:
find_val x m =
Some v ->
m ≋
add_val x v (
remove_val x m).
Proof.
Lemma find_val_grs:
find_val x (
remove_val x m) =
None.
Proof.
Lemma find_val_gro:
x <>
y ->
find_val x (
remove_val y m) =
find_val x m.
Proof.
Lemma find_inst_gempty:
find_inst x (
empty_memory V) =
None.
Proof.
Lemma find_val_gempty:
find_val x (
empty_memory V) =
None.
Proof.
Lemma add_inst_val_comm:
add_inst x m' (
add_val y v m) =
add_val y v (
add_inst x m'
m).
Proof eq_refl.
Lemma add_val_comm:
forall w,
x <>
y ->
add_val x v (
add_val y w m) =
add_val y w (
add_val x v m).
Proof.
Lemma In_find_inst:
forall x (
m :
memory V),
Env.In x (
instances m) ->
exists v,
find_inst x m =
Some v.
Proof.
Lemma find_inst_In:
forall x (
m :
memory V)
v,
find_inst x m =
Some v ->
Env.In x (
instances m).
Proof.
Lemma MapsTo_find_inst:
forall i (
m mi :
memory V),
Env.MapsTo i mi (
instances m) <->
find_inst i m =
Some mi.
Proof.
Combined with orel
Global Instance find_inst_Proper {
A :
Type}:
Proper (
eq ==>
equal_memory ==>
orel equal_memory) (@
find_inst A).
Proof.
Lemma memory_equiv_orel_inst:
forall (
S T :
memory V),
S ≋
T ->
forall x,
find_inst x S ⌈≋⌉
find_inst x T.
Proof.
intros * EM. now setoid_rewrite EM.
Qed.
Lemma memory_equiv_orel_val:
forall (
S T :
memory V),
S ≋
T ->
forall x,
orel eq (
find_val x S) (
find_val x T).
Proof.
intros * EM. now setoid_rewrite EM.
Qed.
Lemma equal_memory_find_inst:
forall (
M :
memory V)
N x Mx,
N ≋
M ->
find_inst x M =
Some Mx ->
exists Nx,
find_inst x N =
Some Nx /\
Nx ≋
Mx.
Proof.
Lemma orel_find_inst_Some (
R :
relation (
memory V)):
forall insts x m,
orel R (
find_inst x insts) (
Some m) ->
exists m',
R m'
m /\
find_inst x insts =
Some m'.
Proof.
Lemma orel_find_val_Some (
R :
relation V):
forall vals x m,
orel R (
find_val x vals) (
Some m) ->
exists m',
R m'
m /\
find_val x vals =
Some m'.
Proof.
End Properties.