Library zoo.language.metatheory
From stdpp Require Import
gmap.
From zoo Require Import
prelude.
From zoo.language Require Export
syntax.
From zoo Require Import
options.
Implicit Types e : expr.
Implicit Types v : val.
Implicit Types env : gmap string val.
Fixpoint occurs x e :=
match e with
| Val _ ⇒
false
| Var y ⇒
x ≟ y
| Rec f y e ⇒
¬ BNamed x ≟ f &&
¬ BNamed x ≟ f &&
¬ BNamed x ≟ y &&
occurs x e
| App e1 e2 ⇒
occurs x e1 ||
occurs x e2
| Let y e1 e2 ⇒
occurs x e1 ||
¬ BNamed x ≟ y &&
occurs x e2
| Unop _ e ⇒
occurs x e
| Binop _ e1 e2 ⇒
occurs x e1 ||
occurs x e2
| Equal e1 e2 ⇒
occurs x e1 ||
occurs x e2
| If e0 e1 e2 ⇒
occurs x e0 ||
occurs x e1 ||
occurs x e2
| For e1 e2 e3 ⇒
occurs x e1 ||
occurs x e2 ||
occurs x e3
| Alloc e1 e2 ⇒
occurs x e1 ||
occurs x e2
| Block _ _ es ⇒
existsb (occurs x) es
| Match e0 y e1 brs ⇒
occurs x e0 ||
(¬ BNamed x ≟ y) && occurs x e1 ||
existsb (λ br,
let pat := br.1 in
forallb (λ y, ¬ BNamed x ≟ y) pat.(pattern_fields) &&
¬ BNamed x ≟ pat.(pattern_as) &&
occurs x br.2
) brs
| GetTag e ⇒
occurs x e
| GetSize e ⇒
occurs x e
| Load e1 e2 ⇒
occurs x e1 ||
occurs x e2
| Store e1 e2 e3 ⇒
occurs x e1 ||
occurs x e2 ||
occurs x e3
| Xchg e1 e2 ⇒
occurs x e1 ||
occurs x e2
| CAS e0 e1 e2 ⇒
occurs x e0 ||
occurs x e1 ||
occurs x e2
| FAA e1 e2 ⇒
occurs x e1 ||
occurs x e2
| Fork e ⇒
occurs x e
| GetLocal ⇒
false
| SetLocal e ⇒
occurs x e
| Proph ⇒
false
| Resolve e0 e1 e2 ⇒
occurs x e0 ||
occurs x e1 ||
occurs x e2
end.
Definition val_recursive v :=
match v with
| ValRecs _ recs ⇒
existsb (λ rec,
match rec.1.1 with
| BAnon ⇒
false
| BNamed f ⇒
existsb (λ rec,
¬ BNamed f ≟ rec.1.2 &&
occurs f rec.2
) recs
end
) recs
| _ ⇒
false
end.
Fixpoint subst (x : string) v e :=
match e with
| Val _ ⇒
e
| Var y ⇒
if x ≟ y then
Val v
else
Var y
| Rec f y e ⇒
Rec
f y
( if BNamed x ≟ f || BNamed x ≟ y then
e
else
subst x v e
)
| App e1 e2 ⇒
App
(subst x v e1)
(subst x v e2)
| Let y e1 e2 ⇒
Let
y
(subst x v e1)
( if BNamed x ≟ y then
e2
else
subst x v e2
)
| Unop op e ⇒
Unop
op
(subst x v e)
| Binop op e1 e2 ⇒
Binop
op
(subst x v e1)
(subst x v e2)
| Equal e1 e2 ⇒
Equal
(subst x v e1)
(subst x v e2)
| If e0 e1 e2 ⇒
If
(subst x v e0)
(subst x v e1)
(subst x v e2)
| For e1 e2 e3 ⇒
For
(subst x v e1)
(subst x v e2)
(subst x v e3)
| Alloc e1 e2 ⇒
Alloc
(subst x v e1)
(subst x v e2)
| Block mut tag es ⇒
Block
mut tag
(subst x v <$> es)
| Match e0 y e1 brs ⇒
Match
(subst x v e0)
y
( if BNamed x ≟ y then
e1
else
subst x v e1
)
( ( λ br,
( br.1,
if
existsb (BNamed x ≟.) br.1.(pattern_fields) ||
BNamed x ≟ br.1.(pattern_as)
then
br.2
else
subst x v br.2
)
) <$> brs
)
| GetTag e ⇒
GetTag
(subst x v e)
| GetSize e ⇒
GetSize
(subst x v e)
| Load e1 e2 ⇒
Load
(subst x v e1)
(subst x v e2)
| Store e1 e2 e3 ⇒
Store
(subst x v e1)
(subst x v e2)
(subst x v e3)
| Xchg e1 e2 ⇒
Xchg
(subst x v e1)
(subst x v e2)
| CAS e0 e1 e2 ⇒
CAS
(subst x v e0)
(subst x v e1)
(subst x v e2)
| FAA e1 e2 ⇒
FAA
(subst x v e1)
(subst x v e2)
| Fork e ⇒
Fork
(subst x v e)
| GetLocal ⇒
GetLocal
| SetLocal e ⇒
SetLocal
(subst x v e)
| Proph ⇒
Proph
| Resolve e0 e1 e2 ⇒
Resolve
(subst x v e0)
(subst x v e1)
(subst x v e2)
end.
#[global] Arguments subst _ _ !_ / : assert.
Definition subst' x v :=
match x with
| BNamed x ⇒
subst x v
| BAnon ⇒
id
end.
#[global] Arguments subst' !_ _ / _ : assert.
Fixpoint subst_list xs vs e :=
match xs with
| [] ⇒
e
| x :: xs ⇒
match vs with
| [] ⇒
e
| v :: vs ⇒
subst' x v $ subst_list xs vs e
end
end.
#[global] Arguments subst_list !_ !_ _ / : assert.
Lemma subst_val x v1 v2 :
subst x v1 (Val v2) = Val v2.
Lemma subst'_val x v1 v2 :
subst' x v1 (Val v2) = Val v2.
gmap.
From zoo Require Import
prelude.
From zoo.language Require Export
syntax.
From zoo Require Import
options.
Implicit Types e : expr.
Implicit Types v : val.
Implicit Types env : gmap string val.
Fixpoint occurs x e :=
match e with
| Val _ ⇒
false
| Var y ⇒
x ≟ y
| Rec f y e ⇒
¬ BNamed x ≟ f &&
¬ BNamed x ≟ f &&
¬ BNamed x ≟ y &&
occurs x e
| App e1 e2 ⇒
occurs x e1 ||
occurs x e2
| Let y e1 e2 ⇒
occurs x e1 ||
¬ BNamed x ≟ y &&
occurs x e2
| Unop _ e ⇒
occurs x e
| Binop _ e1 e2 ⇒
occurs x e1 ||
occurs x e2
| Equal e1 e2 ⇒
occurs x e1 ||
occurs x e2
| If e0 e1 e2 ⇒
occurs x e0 ||
occurs x e1 ||
occurs x e2
| For e1 e2 e3 ⇒
occurs x e1 ||
occurs x e2 ||
occurs x e3
| Alloc e1 e2 ⇒
occurs x e1 ||
occurs x e2
| Block _ _ es ⇒
existsb (occurs x) es
| Match e0 y e1 brs ⇒
occurs x e0 ||
(¬ BNamed x ≟ y) && occurs x e1 ||
existsb (λ br,
let pat := br.1 in
forallb (λ y, ¬ BNamed x ≟ y) pat.(pattern_fields) &&
¬ BNamed x ≟ pat.(pattern_as) &&
occurs x br.2
) brs
| GetTag e ⇒
occurs x e
| GetSize e ⇒
occurs x e
| Load e1 e2 ⇒
occurs x e1 ||
occurs x e2
| Store e1 e2 e3 ⇒
occurs x e1 ||
occurs x e2 ||
occurs x e3
| Xchg e1 e2 ⇒
occurs x e1 ||
occurs x e2
| CAS e0 e1 e2 ⇒
occurs x e0 ||
occurs x e1 ||
occurs x e2
| FAA e1 e2 ⇒
occurs x e1 ||
occurs x e2
| Fork e ⇒
occurs x e
| GetLocal ⇒
false
| SetLocal e ⇒
occurs x e
| Proph ⇒
false
| Resolve e0 e1 e2 ⇒
occurs x e0 ||
occurs x e1 ||
occurs x e2
end.
Definition val_recursive v :=
match v with
| ValRecs _ recs ⇒
existsb (λ rec,
match rec.1.1 with
| BAnon ⇒
false
| BNamed f ⇒
existsb (λ rec,
¬ BNamed f ≟ rec.1.2 &&
occurs f rec.2
) recs
end
) recs
| _ ⇒
false
end.
Fixpoint subst (x : string) v e :=
match e with
| Val _ ⇒
e
| Var y ⇒
if x ≟ y then
Val v
else
Var y
| Rec f y e ⇒
Rec
f y
( if BNamed x ≟ f || BNamed x ≟ y then
e
else
subst x v e
)
| App e1 e2 ⇒
App
(subst x v e1)
(subst x v e2)
| Let y e1 e2 ⇒
Let
y
(subst x v e1)
( if BNamed x ≟ y then
e2
else
subst x v e2
)
| Unop op e ⇒
Unop
op
(subst x v e)
| Binop op e1 e2 ⇒
Binop
op
(subst x v e1)
(subst x v e2)
| Equal e1 e2 ⇒
Equal
(subst x v e1)
(subst x v e2)
| If e0 e1 e2 ⇒
If
(subst x v e0)
(subst x v e1)
(subst x v e2)
| For e1 e2 e3 ⇒
For
(subst x v e1)
(subst x v e2)
(subst x v e3)
| Alloc e1 e2 ⇒
Alloc
(subst x v e1)
(subst x v e2)
| Block mut tag es ⇒
Block
mut tag
(subst x v <$> es)
| Match e0 y e1 brs ⇒
Match
(subst x v e0)
y
( if BNamed x ≟ y then
e1
else
subst x v e1
)
( ( λ br,
( br.1,
if
existsb (BNamed x ≟.) br.1.(pattern_fields) ||
BNamed x ≟ br.1.(pattern_as)
then
br.2
else
subst x v br.2
)
) <$> brs
)
| GetTag e ⇒
GetTag
(subst x v e)
| GetSize e ⇒
GetSize
(subst x v e)
| Load e1 e2 ⇒
Load
(subst x v e1)
(subst x v e2)
| Store e1 e2 e3 ⇒
Store
(subst x v e1)
(subst x v e2)
(subst x v e3)
| Xchg e1 e2 ⇒
Xchg
(subst x v e1)
(subst x v e2)
| CAS e0 e1 e2 ⇒
CAS
(subst x v e0)
(subst x v e1)
(subst x v e2)
| FAA e1 e2 ⇒
FAA
(subst x v e1)
(subst x v e2)
| Fork e ⇒
Fork
(subst x v e)
| GetLocal ⇒
GetLocal
| SetLocal e ⇒
SetLocal
(subst x v e)
| Proph ⇒
Proph
| Resolve e0 e1 e2 ⇒
Resolve
(subst x v e0)
(subst x v e1)
(subst x v e2)
end.
#[global] Arguments subst _ _ !_ / : assert.
Definition subst' x v :=
match x with
| BNamed x ⇒
subst x v
| BAnon ⇒
id
end.
#[global] Arguments subst' !_ _ / _ : assert.
Fixpoint subst_list xs vs e :=
match xs with
| [] ⇒
e
| x :: xs ⇒
match vs with
| [] ⇒
e
| v :: vs ⇒
subst' x v $ subst_list xs vs e
end
end.
#[global] Arguments subst_list !_ !_ _ / : assert.
Lemma subst_val x v1 v2 :
subst x v1 (Val v2) = Val v2.
Lemma subst'_val x v1 v2 :
subst' x v1 (Val v2) = Val v2.