From Velus Require Import Common.
From Coq Require Import String.
From Coq Require Import Ascii.
From Coq Require Import List.
Import List.ListNotations.
Open Scope bool_scope.
ident <-> string conversion
Axiom pos_to_str:
ident ->
string.
Axiom str_to_pos:
string ->
ident.
Axiom str_to_pos_injective:
forall x x',
str_to_pos x =
str_to_pos x' ->
x =
x'.
Axiom pos_to_str_equiv:
forall x,
pos_to_str (
str_to_pos x) =
x.
Fixpoint In_str (
x:
ascii) (
s:
string):
Prop :=
match s with
|
EmptyString =>
False
|
String x'
s =>
x' =
x \/
In_str x s
end.
Scheme Equality for ascii.
Fixpoint mem_str (
x:
ascii) (
s:
string):
bool :=
match s with
|
EmptyString =>
false
|
String x'
s => (
ascii_beq x'
x ||
mem_str x s)%
bool
end.
Lemma mem_In_str:
forall x s,
In_str x s <->
mem_str x s =
true.
Proof.
Lemma not_mem_In_str:
forall x s,
~
In_str x s <->
mem_str x s =
false.
Proof.
Definition sep:
ascii := "$"%
char.
Module Export Ids <:
IDS.
Definition self :=
str_to_pos "
self".
Definition out :=
str_to_pos "
out".
Definition temp :=
str_to_pos "
temp".
Definition fun_id:
ident :=
str_to_pos "
fun".
Definition sync_id:
ident :=
str_to_pos "
sync".
Definition main_id:
ident :=
str_to_pos "
main".
Definition main_proved_id:
ident :=
str_to_pos "
main_proved".
Definition main_sync_id:
ident :=
str_to_pos "
main_sync".
Definition step :=
str_to_pos "
step".
Definition reset :=
str_to_pos "
reset".
Definition glob :=
str_to_pos "
glob".
Definition elab :=
str_to_pos "
elab".
Definition norm1 :=
str_to_pos "
norm1".
Definition norm2 :=
str_to_pos "
norm2".
Definition obc2c :=
str_to_pos "
obc2c".
Definition default := 1%
positive.
Ltac prove_str_to_pos_neq :=
match goal with
| |- ?
x1 <> ?
x2 =>
intros Heq;
apply str_to_pos_injective in Heq;
inv Heq
end.
Definition gensym_prefs := [
elab;
norm1;
norm2].
Lemma gensym_prefs_NoDup :
NoDup gensym_prefs.
Proof.
unfold gensym_prefs.
repeat constructor;
auto.
1,2:
repeat rewrite not_in_cons;
repeat split;
auto.
1-3:
prove_str_to_pos_neq.
Qed.
Lemma self_not_out:
self <>
out.
Proof.
prove_str_to_pos_neq. Qed.
Hint Resolve self_not_out.
Lemma reset_not_step:
reset <>
step.
Proof.
prove_str_to_pos_neq. Qed.
Hint Resolve reset_not_step.
Lemma fun_not_out:
fun_id <>
out.
Proof.
prove_str_to_pos_neq. Qed.
Hint Resolve fun_not_out.
Lemma fun_not_glob:
fun_id <>
glob.
Proof.
prove_str_to_pos_neq. Qed.
Hint Resolve fun_not_glob.
Fact obc2c_not_in_gensym_prefs :
~
In obc2c gensym_prefs.
Proof.
Hint Resolve obc2c_not_in_gensym_prefs.
Fact self_not_in_gensym_prefs :
~
In self gensym_prefs.
Proof.
Hint Resolve self_not_in_gensym_prefs.
Fact temp_not_in_gensym_prefs :
~
In temp gensym_prefs.
Proof.
Hint Resolve temp_not_in_gensym_prefs.
Definition atom x := ~
In_str sep (
pos_to_str x).
Definition is_atom x :=
negb (
mem_str sep (
pos_to_str x)).
Lemma is_atom_spec :
forall x,
is_atom x =
true <->
atom x.
Proof.
Local Ltac prove_atom :=
match goal with
| |-
atom ?
x =>
unfold atom,
x;
rewrite pos_to_str_equiv;
rewrite not_mem_In_str;
reflexivity
end.
Lemma self_atom:
atom self.
Proof.
prove_atom. Qed.
Lemma out_atom:
atom out.
Proof.
prove_atom. Qed.
Lemma temp_atom:
atom temp.
Proof.
prove_atom. Qed.
Lemma fun_id_atom:
atom fun_id.
Proof.
prove_atom. Qed.
Lemma sync_id_atom:
atom sync_id.
Proof.
prove_atom. Qed.
Lemma main_id_atom:
atom main_id.
Proof.
prove_atom. Qed.
Lemma main_proved_id_atom:
atom main_proved_id.
Proof.
prove_atom. Qed.
Lemma main_sync_id_atom:
atom main_sync_id.
Proof.
prove_atom. Qed.
Lemma step_atom:
atom step.
Proof.
prove_atom. Qed.
Lemma reset_atom:
atom reset.
Proof.
prove_atom. Qed.
Lemma glob_atom:
atom glob.
Proof.
prove_atom. Qed.
Lemma elab_atom:
atom elab.
Proof.
prove_atom. Qed.
Lemma norm1_atom:
atom norm1.
Proof.
prove_atom. Qed.
Lemma norm2_atom:
atom norm2.
Proof.
prove_atom. Qed.
Lemma obc2c_atom:
atom obc2c.
Proof.
prove_atom. Qed.
Hint Resolve step_atom reset_atom fun_id_atom sync_id_atom
out_atom main_id_atom main_proved_id_atom main_sync_id_atom
self_atom glob_atom elab_atom norm1_atom norm2_atom obc2c_atom.
Axiom prefix :
ident ->
ident ->
ident.
Axiom prefix_not_atom:
forall pref id,
~
atom (
prefix pref id).
Hint Resolve prefix_not_atom.
Axiom prefix_injective':
forall pref id pref'
id',
pref <>
pref' \/
id <>
id' ->
prefix pref id <>
prefix pref'
id'.
Corollary prefix_injective:
forall pref id pref'
id',
prefix pref id =
prefix pref'
id' ->
pref =
pref' /\
id =
id'.
Proof.
intros *
Heq.
destruct (
ident_eq_dec pref pref'), (
ident_eq_dec id id');
auto.
1-3:
exfalso;
eapply prefix_injective'
in Heq;
eauto.
Qed.
Definition prefix_fun (
f c:
ident):
ident :=
prefix fun_id (
prefix f c).
Definition prefix_out (
f o:
ident):
ident :=
prefix out (
prefix f o).
Definition prefix_temp (
f c:
ident):
ident :=
prefix temp (
prefix f c).
Lemma prefix_fun_injective:
forall c c'
f f',
prefix_fun c f =
prefix_fun c'
f' ->
c =
c' /\
f =
f'.
Proof.
Lemma prefix_out_injective:
forall c c'
f f',
prefix_out c f =
prefix_out c'
f' ->
c =
c' /\
f =
f'.
Proof.
Lemma prefix_fun_not_out:
forall c f c'
f',
prefix_fun c f <>
prefix_out c'
f'.
Proof.
intros *.
eapply prefix_injective'. left.
prove_str_to_pos_neq.
Qed.
Definition prefix_glob (
id:
ident):
ident :=
prefix glob id.
Lemma main_not_glob:
forall x,
prefix_glob x <>
main_id.
Proof.
Lemma main_proved_not_glob:
forall x,
prefix_glob x <>
main_proved_id.
Proof.
Lemma sync_not_glob:
forall x,
prefix_glob x <>
sync_id.
Proof.
Lemma main_sync_not_glob:
forall x,
prefix_glob x <>
main_sync_id.
Proof.
Lemma self_not_glob:
forall x,
prefix_glob x <>
self.
Proof.
Lemma prefix_glob_injective:
forall x x',
prefix_glob x =
prefix_glob x' ->
x =
x'.
Proof.
Lemma glob_not_in_prefixed:
forall {
A} (
xs:
list (
ident *
A))
ps,
Forall (
fun x =>
exists m c,
x =
prefix_fun m c)
ps ->
Forall (
fun z => ~
In z ps) (
map (
fun xt =>
prefix_glob (
fst xt))
xs).
Proof.
induction xs as [|(
x,
t)];
simpl;
intros *
Pref;
auto.
constructor;
auto.
intro Hin.
eapply Forall_forall in Hin;
eauto;
simpl in Hin.
destruct Hin as (?&?&
Hpre).
eapply prefix_injective in Hpre as (
Heq&?);
subst.
contradict Heq.
prove_str_to_pos_neq.
Qed.
Lemma NoDupMembers_glob:
forall {
A} (
ys xs:
list (
ident *
A)),
NoDupMembers (
xs ++
ys) ->
Forall (
fun z => ~
In z (
map (
fun xt =>
prefix_glob (
fst xt))
xs))
(
map (
fun xt =>
prefix_glob (
fst xt))
ys).
Proof.
Name generation with fresh identifiers
Axiom gensym :
ident ->
ident ->
ident.
Axiom gensym_not_atom:
forall pref x,
~
atom (
gensym pref x).
Axiom gensym_injective':
forall pref id pref'
id',
pref <>
pref' \/
id <>
id' ->
gensym pref id <>
gensym pref'
id'.
Corollary gensym_injective:
forall pref id pref'
id',
gensym pref id =
gensym pref'
id' ->
pref =
pref' /\
id =
id'.
Proof.
intros *
Heq.
destruct (
ident_eq_dec pref pref'), (
ident_eq_dec id id');
auto.
1-3:
exfalso;
eapply gensym_injective'
in Heq;
eauto.
Qed.
Definition AtomOrGensym (
prefs :
PS.t) (
id :
ident) :=
atom id \/
PS.Exists (
fun pre =>
exists n,
id =
gensym pre n)
prefs.
Axiom prefix_gensym_injective':
forall pref id pref'
id',
pref <>
pref' ->
prefix pref id <>
gensym pref'
id'.
Corollary prefix_gensym_injective:
forall pref id pref'
id',
prefix pref id =
gensym pref'
id' ->
pref =
pref'.
Proof.
intros *
Heq.
destruct (
ident_eq_dec pref pref');
auto.
exfalso.
eapply prefix_gensym_injective'
in n;
eauto.
Qed.
End Ids.