mirror of
https://github.com/achlipala/frap.git
synced 2024-12-01 00:26:18 +00:00
Start of BasicSyntax code
This commit is contained in:
parent
e5898976ab
commit
f8945106da
10 changed files with 837 additions and 0 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -9,3 +9,7 @@
|
||||||
*.blg
|
*.blg
|
||||||
*.ilg
|
*.ilg
|
||||||
*.ind
|
*.ind
|
||||||
|
Makefile.coq
|
||||||
|
*.glob
|
||||||
|
*.v.d
|
||||||
|
*.vo
|
||||||
|
|
250
BasicSyntax.v
Normal file
250
BasicSyntax.v
Normal file
|
@ -0,0 +1,250 @@
|
||||||
|
(** Formal Reasoning About Programs <http://adam.chlipala.net/frap/>
|
||||||
|
* Chapter 2: Basic Program Syntax
|
||||||
|
* Author: Adam Chlipala
|
||||||
|
* License: https://creativecommons.org/licenses/by-nc-nd/4.0/ *)
|
||||||
|
|
||||||
|
Require Import Frap.
|
||||||
|
|
||||||
|
|
||||||
|
Module ArithWithConstants.
|
||||||
|
|
||||||
|
Inductive arith : Set :=
|
||||||
|
| Const (n : nat)
|
||||||
|
| Plus (e1 e2 : arith)
|
||||||
|
| Times (e1 e2 : arith).
|
||||||
|
|
||||||
|
Example ex1 := Const 42.
|
||||||
|
Example ex2 := Plus (Const 1) (Times (Const 2) (Const 3)).
|
||||||
|
|
||||||
|
Fixpoint size (e : arith) : nat :=
|
||||||
|
match e with
|
||||||
|
| Const _ => 1
|
||||||
|
| Plus e1 e2 => 1 + size e1 + size e2
|
||||||
|
| Times e1 e2 => 1 + size e1 + size e2
|
||||||
|
end.
|
||||||
|
|
||||||
|
Compute size ex1.
|
||||||
|
Compute size ex2.
|
||||||
|
|
||||||
|
Fixpoint depth (e : arith) : nat :=
|
||||||
|
match e with
|
||||||
|
| Const _ => 1
|
||||||
|
| Plus e1 e2 => 1 + max (depth e1) (depth e2)
|
||||||
|
| Times e1 e2 => 1 + max (depth e1) (depth e2)
|
||||||
|
end.
|
||||||
|
|
||||||
|
Compute depth ex1.
|
||||||
|
Compute size ex2.
|
||||||
|
|
||||||
|
Theorem depth_le_size : forall e, depth e <= size e.
|
||||||
|
Proof.
|
||||||
|
induct e.
|
||||||
|
|
||||||
|
simplify.
|
||||||
|
linear_arithmetic.
|
||||||
|
|
||||||
|
simplify.
|
||||||
|
linear_arithmetic.
|
||||||
|
|
||||||
|
simplify.
|
||||||
|
linear_arithmetic.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem depth_le_size_snazzy : forall e, depth e <= size e.
|
||||||
|
Proof.
|
||||||
|
induct e; simplify; linear_arithmetic.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Fixpoint commuter (e : arith) : arith :=
|
||||||
|
match e with
|
||||||
|
| Const _ => e
|
||||||
|
| Plus e1 e2 => Plus (commuter e2) (commuter e1)
|
||||||
|
| Times e1 e2 => Times (commuter e2) (commuter e1)
|
||||||
|
end.
|
||||||
|
|
||||||
|
Compute commuter ex1.
|
||||||
|
Compute commuter ex2.
|
||||||
|
|
||||||
|
Theorem size_commuter : forall e, size (commuter e) = size e.
|
||||||
|
Proof.
|
||||||
|
induct e; simplify; linear_arithmetic.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem depth_commuter : forall e, depth (commuter e) = depth e.
|
||||||
|
Proof.
|
||||||
|
induct e; simplify; linear_arithmetic.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem commuter_inverse : forall e, commuter (commuter e) = e.
|
||||||
|
Proof.
|
||||||
|
induct e; simplify; equality.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
End ArithWithConstants.
|
||||||
|
|
||||||
|
Module ArithWithVariables.
|
||||||
|
|
||||||
|
Inductive arith : Set :=
|
||||||
|
| Const (n : nat)
|
||||||
|
| Var (x : var)
|
||||||
|
| Plus (e1 e2 : arith)
|
||||||
|
| Times (e1 e2 : arith).
|
||||||
|
|
||||||
|
Example ex1 := Const 42.
|
||||||
|
Example ex2 := Plus (Const 1) (Times (Var "x") (Const 3)).
|
||||||
|
|
||||||
|
Fixpoint size (e : arith) : nat :=
|
||||||
|
match e with
|
||||||
|
| Const _ => 1
|
||||||
|
| Var _ => 1
|
||||||
|
| Plus e1 e2 => 1 + size e1 + size e2
|
||||||
|
| Times e1 e2 => 1 + size e1 + size e2
|
||||||
|
end.
|
||||||
|
|
||||||
|
Compute size ex1.
|
||||||
|
Compute size ex2.
|
||||||
|
|
||||||
|
Fixpoint depth (e : arith) : nat :=
|
||||||
|
match e with
|
||||||
|
| Const _ => 1
|
||||||
|
| Var _ => 1
|
||||||
|
| Plus e1 e2 => 1 + max (depth e1) (depth e2)
|
||||||
|
| Times e1 e2 => 1 + max (depth e1) (depth e2)
|
||||||
|
end.
|
||||||
|
|
||||||
|
Compute depth ex1.
|
||||||
|
Compute size ex2.
|
||||||
|
|
||||||
|
Theorem depth_le_size : forall e, depth e <= size e.
|
||||||
|
Proof.
|
||||||
|
induct e; simplify; linear_arithmetic.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Fixpoint commuter (e : arith) : arith :=
|
||||||
|
match e with
|
||||||
|
| Const _ => e
|
||||||
|
| Var _ => e
|
||||||
|
| Plus e1 e2 => Plus (commuter e2) (commuter e1)
|
||||||
|
| Times e1 e2 => Times (commuter e2) (commuter e1)
|
||||||
|
end.
|
||||||
|
|
||||||
|
Compute commuter ex1.
|
||||||
|
Compute commuter ex2.
|
||||||
|
|
||||||
|
Theorem size_commuter : forall e, size (commuter e) = size e.
|
||||||
|
Proof.
|
||||||
|
induct e; simplify; linear_arithmetic.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem depth_commuter : forall e, depth (commuter e) = depth e.
|
||||||
|
Proof.
|
||||||
|
induct e; simplify; linear_arithmetic.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem commuter_inverse : forall e, commuter (commuter e) = e.
|
||||||
|
Proof.
|
||||||
|
induct e; simplify; equality.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Fixpoint substitute (inThis : arith) (replaceThis : var) (withThis : arith) : arith :=
|
||||||
|
match inThis with
|
||||||
|
| Const _ => inThis
|
||||||
|
| Var x => if x ==v replaceThis then withThis else inThis
|
||||||
|
| Plus e1 e2 => Plus (substitute e1 replaceThis withThis) (substitute e2 replaceThis withThis)
|
||||||
|
| Times e1 e2 => Times (substitute e1 replaceThis withThis) (substitute e2 replaceThis withThis)
|
||||||
|
end.
|
||||||
|
|
||||||
|
Theorem substitute_depth : forall replaceThis withThis inThis,
|
||||||
|
depth (substitute inThis replaceThis withThis) <= depth inThis + depth withThis.
|
||||||
|
Proof.
|
||||||
|
induct inThis.
|
||||||
|
|
||||||
|
simplify.
|
||||||
|
linear_arithmetic.
|
||||||
|
|
||||||
|
simplify.
|
||||||
|
cases (x ==v replaceThis).
|
||||||
|
linear_arithmetic.
|
||||||
|
simplify.
|
||||||
|
linear_arithmetic.
|
||||||
|
|
||||||
|
simplify.
|
||||||
|
linear_arithmetic.
|
||||||
|
|
||||||
|
simplify.
|
||||||
|
linear_arithmetic.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem substitute_depth_snazzy : forall replaceThis withThis inThis,
|
||||||
|
depth (substitute inThis replaceThis withThis) <= depth inThis + depth withThis.
|
||||||
|
Proof.
|
||||||
|
induct inThis; simplify;
|
||||||
|
try match goal with
|
||||||
|
| [ |- context[if ?a ==v ?b then _ else _] ] => cases (a ==v b); simplify
|
||||||
|
end; linear_arithmetic.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem substitute_self : forall replaceThis inThis,
|
||||||
|
substitute inThis replaceThis (Var replaceThis) = inThis.
|
||||||
|
Proof.
|
||||||
|
induct inThis; simplify;
|
||||||
|
try match goal with
|
||||||
|
| [ |- context[if ?a ==v ?b then _ else _] ] => cases (a ==v b); simplify
|
||||||
|
end; equality.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem substitute_commuter : forall replaceThis withThis inThis,
|
||||||
|
commuter (substitute inThis replaceThis withThis)
|
||||||
|
= substitute (commuter inThis) replaceThis (commuter withThis).
|
||||||
|
Proof.
|
||||||
|
induct inThis; simplify;
|
||||||
|
try match goal with
|
||||||
|
| [ |- context[if ?a ==v ?b then _ else _] ] => cases (a ==v b); simplify
|
||||||
|
end; equality.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Fixpoint constantFold (e : arith) : arith :=
|
||||||
|
match e with
|
||||||
|
| Const _ => e
|
||||||
|
| Var _ => e
|
||||||
|
| Plus e1 e2 =>
|
||||||
|
let e1' := constantFold e1 in
|
||||||
|
let e2' := constantFold e2 in
|
||||||
|
match e1', e2' with
|
||||||
|
| Const n1, Const n2 => Const (n1 + n2)
|
||||||
|
| Const 0, _ => e2'
|
||||||
|
| _, Const 0 => e1'
|
||||||
|
| _, _ => Plus e1' e2'
|
||||||
|
end
|
||||||
|
| Times e1 e2 =>
|
||||||
|
let e1' := constantFold e1 in
|
||||||
|
let e2' := constantFold e2 in
|
||||||
|
match e1', e2' with
|
||||||
|
| Const n1, Const n2 => Const (n1 * n2)
|
||||||
|
| Const 1, _ => e2'
|
||||||
|
| _, Const 1 => e1'
|
||||||
|
| Const 0, _ => Const 0
|
||||||
|
| _, Const 0 => Const 0
|
||||||
|
| _, _ => Times e1' e2'
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
Theorem size_constantFold : forall e, size (constantFold e) <= size e.
|
||||||
|
Proof.
|
||||||
|
induct e; simplify;
|
||||||
|
repeat match goal with
|
||||||
|
| [ |- context[match ?E with _ => _ end] ] => cases E; simplify
|
||||||
|
end; linear_arithmetic.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem commuter_constantFold : forall e, commuter (constantFold e) = constantFold (commuter e).
|
||||||
|
Proof.
|
||||||
|
induct e; simplify;
|
||||||
|
repeat match goal with
|
||||||
|
| [ |- context[match ?E with _ => _ end] ] => cases E; simplify
|
||||||
|
| [ H : ?f _ = ?f _ |- _ ] => invert H
|
||||||
|
| [ |- ?f _ = ?f _ ] => f_equal
|
||||||
|
end; equality || linear_arithmetic || ring.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
End ArithWithVariables.
|
70
Frap.v
Normal file
70
Frap.v
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
Require Import String Arith Omega Program Sets Relations Map Var Invariant.
|
||||||
|
Export String Arith Sets Relations Map Var Invariant.
|
||||||
|
Require Import List.
|
||||||
|
Export ListNotations.
|
||||||
|
Open Scope string_scope.
|
||||||
|
|
||||||
|
Ltac inductN n :=
|
||||||
|
match goal with
|
||||||
|
| [ |- forall x : ?E, _ ] =>
|
||||||
|
match type of E with
|
||||||
|
| Prop =>
|
||||||
|
let H := fresh in intro H;
|
||||||
|
match n with
|
||||||
|
| 1 => dependent induction H
|
||||||
|
| S ?n' => inductN n'
|
||||||
|
end
|
||||||
|
| _ => intro; inductN n
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
Ltac induct e := inductN e || dependent induction e.
|
||||||
|
|
||||||
|
Ltac invert' H := inversion H; clear H; subst.
|
||||||
|
|
||||||
|
Ltac invertN n :=
|
||||||
|
match goal with
|
||||||
|
| [ |- forall x : ?E, _ ] =>
|
||||||
|
match type of E with
|
||||||
|
| Prop =>
|
||||||
|
let H := fresh in intro H;
|
||||||
|
match n with
|
||||||
|
| 1 => invert' H
|
||||||
|
| S ?n' => invertN n'
|
||||||
|
end
|
||||||
|
| _ => intro; invertN n
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
Ltac invert e := invertN e || invert' e.
|
||||||
|
|
||||||
|
Ltac invert0 e := invert e; fail.
|
||||||
|
Ltac invert1 e := invert0 e || (invert e; []).
|
||||||
|
Ltac invert2 e := invert1 e || (invert e; [|]).
|
||||||
|
|
||||||
|
Ltac simplify := simpl in *.
|
||||||
|
|
||||||
|
Ltac linear_arithmetic :=
|
||||||
|
repeat match goal with
|
||||||
|
| [ |- context[max ?a ?b] ] =>
|
||||||
|
let Heq := fresh "Heq" in destruct (Max.max_spec a b) as [[? Heq] | [? Heq]];
|
||||||
|
rewrite Heq in *; clear Heq
|
||||||
|
| [ _ : context[max ?a ?b] |- _ ] =>
|
||||||
|
let Heq := fresh "Heq" in destruct (Max.max_spec a b) as [[? Heq] | [? Heq]];
|
||||||
|
rewrite Heq in *; clear Heq
|
||||||
|
| [ |- context[min ?a ?b] ] =>
|
||||||
|
let Heq := fresh "Heq" in destruct (Min.min_spec a b) as [[? Heq] | [? Heq]];
|
||||||
|
rewrite Heq in *; clear Heq
|
||||||
|
| [ _ : context[min ?a ?b] |- _ ] =>
|
||||||
|
let Heq := fresh "Heq" in destruct (Min.min_spec a b) as [[? Heq] | [? Heq]];
|
||||||
|
rewrite Heq in *; clear Heq
|
||||||
|
end; omega.
|
||||||
|
|
||||||
|
Ltac equality := congruence.
|
||||||
|
|
||||||
|
Ltac cases E :=
|
||||||
|
(is_var E; destruct E)
|
||||||
|
|| match type of E with
|
||||||
|
| {_} + {_} => destruct E
|
||||||
|
| _ => let Heq := fresh "Heq" in destruct E eqn:Heq
|
||||||
|
end.
|
30
Invariant.v
Normal file
30
Invariant.v
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
Require Import Relations.
|
||||||
|
|
||||||
|
Set Implicit Arguments.
|
||||||
|
|
||||||
|
|
||||||
|
Section Invariant.
|
||||||
|
Variable state : Type.
|
||||||
|
Variable step : state -> state -> Prop.
|
||||||
|
Variable invariant : state -> Prop.
|
||||||
|
|
||||||
|
Hint Constructors trc.
|
||||||
|
|
||||||
|
Definition safe (s : state) :=
|
||||||
|
forall s', step^* s s' -> invariant s'.
|
||||||
|
|
||||||
|
Variable s0 : state.
|
||||||
|
|
||||||
|
Hypothesis Hinitial : invariant s0.
|
||||||
|
|
||||||
|
Hypothesis Hstep : forall s s', invariant s -> step s s' -> invariant s'.
|
||||||
|
|
||||||
|
Lemma safety : safe s0.
|
||||||
|
Proof.
|
||||||
|
generalize dependent s0.
|
||||||
|
unfold safe.
|
||||||
|
induction 2; eauto.
|
||||||
|
Qed.
|
||||||
|
End Invariant.
|
||||||
|
|
||||||
|
Hint Resolve safety.
|
14
Makefile
14
Makefile
|
@ -1,6 +1,20 @@
|
||||||
|
.PHONY: all coq
|
||||||
|
|
||||||
|
all: frap.pdf coq
|
||||||
|
|
||||||
frap.pdf: frap.tex Makefile
|
frap.pdf: frap.tex Makefile
|
||||||
pdflatex frap
|
pdflatex frap
|
||||||
pdflatex frap
|
pdflatex frap
|
||||||
makeindex frap
|
makeindex frap
|
||||||
pdflatex frap
|
pdflatex frap
|
||||||
pdflatex frap
|
pdflatex frap
|
||||||
|
|
||||||
|
coq: Makefile.coq
|
||||||
|
$(MAKE) -f Makefile.coq
|
||||||
|
|
||||||
|
Makefile.coq: Makefile _CoqProject *.v
|
||||||
|
coq_makefile -f _CoqProject -o Makefile.coq
|
||||||
|
|
||||||
|
clean:: Makefile.coq
|
||||||
|
$(MAKE) -f Makefile.coq clean
|
||||||
|
rm -f Makefile.coq
|
||||||
|
|
216
Map.v
Normal file
216
Map.v
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
Require Import Classical Sets ClassicalEpsilon FunctionalExtensionality.
|
||||||
|
|
||||||
|
Set Implicit Arguments.
|
||||||
|
|
||||||
|
Module Type S.
|
||||||
|
Parameter map : Type -> Type -> Type.
|
||||||
|
|
||||||
|
Parameter empty : forall A B, map A B.
|
||||||
|
Parameter add : forall A B, map A B -> A -> B -> map A B.
|
||||||
|
Parameter join : forall A B, map A B -> map A B -> map A B.
|
||||||
|
Parameter lookup : forall A B, map A B -> A -> option B.
|
||||||
|
Parameter includes : forall A B, map A B -> map A B -> Prop.
|
||||||
|
|
||||||
|
Notation "$0" := (empty _ _).
|
||||||
|
Notation "m $+ ( k , v )" := (add m k v) (at level 50, left associativity).
|
||||||
|
Infix "$++" := join (at level 50, left associativity).
|
||||||
|
Infix "$?" := lookup (at level 50, no associativity).
|
||||||
|
Infix "$<=" := includes (at level 90).
|
||||||
|
|
||||||
|
Parameter dom : forall A B, map A B -> set A.
|
||||||
|
|
||||||
|
Axiom map_ext : forall A B (m1 m2 : map A B),
|
||||||
|
(forall k, m1 $? k = m2 $? k)
|
||||||
|
-> m1 = m2.
|
||||||
|
|
||||||
|
Axiom lookup_empty : forall A B k, empty A B $? k = None.
|
||||||
|
|
||||||
|
Axiom includes_lookup : forall A B (m m' : map A B) k v,
|
||||||
|
m $? k = Some v
|
||||||
|
-> m $<= m'
|
||||||
|
-> lookup m' k = Some v.
|
||||||
|
|
||||||
|
Axiom includes_add : forall A B (m m' : map A B) k v,
|
||||||
|
m $<= m'
|
||||||
|
-> add m k v $<= add m' k v.
|
||||||
|
|
||||||
|
Axiom lookup_add_eq : forall A B (m : map A B) k v,
|
||||||
|
add m k v $? k = Some v.
|
||||||
|
|
||||||
|
Axiom lookup_add_ne : forall A B (m : map A B) k k' v,
|
||||||
|
k' <> k
|
||||||
|
-> add m k v $? k' = m $? k'.
|
||||||
|
|
||||||
|
Axiom lookup_join1 : forall A B (m1 m2 : map A B) k,
|
||||||
|
k \in dom m1
|
||||||
|
-> (m1 $++ m2) $? k = m1 $? k.
|
||||||
|
|
||||||
|
Axiom lookup_join2 : forall A B (m1 m2 : map A B) k,
|
||||||
|
~k \in dom m1
|
||||||
|
-> (m1 $++ m2) $? k = m2 $? k.
|
||||||
|
|
||||||
|
Axiom join_comm : forall A B (m1 m2 : map A B),
|
||||||
|
dom m1 \cap dom m2 = {}
|
||||||
|
-> m1 $++ m2 = m2 $++ m1.
|
||||||
|
|
||||||
|
Axiom join_assoc : forall A B (m1 m2 m3 : map A B),
|
||||||
|
(m1 $++ m2) $++ m3 = m1 $++ (m2 $++ m3).
|
||||||
|
|
||||||
|
Axiom empty_includes : forall A B (m : map A B), empty A B $<= m.
|
||||||
|
|
||||||
|
Axiom dom_empty : forall A B, dom (empty A B) = {}.
|
||||||
|
|
||||||
|
Axiom dom_add : forall A B (m : map A B) (k : A) (v : B),
|
||||||
|
dom (add m k v) = {k} \cup dom m.
|
||||||
|
|
||||||
|
Hint Extern 1 => match goal with
|
||||||
|
| [ H : lookup (empty _ _) _ = Some _ |- _ ] =>
|
||||||
|
rewrite lookup_empty in H; discriminate
|
||||||
|
end.
|
||||||
|
|
||||||
|
Hint Resolve includes_lookup includes_add empty_includes.
|
||||||
|
|
||||||
|
Hint Rewrite lookup_add_eq lookup_add_ne using congruence.
|
||||||
|
|
||||||
|
Ltac maps_equal :=
|
||||||
|
apply map_ext; intros;
|
||||||
|
repeat (subst; autorewrite with core; try reflexivity;
|
||||||
|
match goal with
|
||||||
|
| [ |- context[lookup (add _ ?k _) ?k' ] ] => destruct (classic (k = k')); subst
|
||||||
|
end).
|
||||||
|
|
||||||
|
Hint Extern 3 (_ = _) => maps_equal.
|
||||||
|
End S.
|
||||||
|
|
||||||
|
Module M : S.
|
||||||
|
Definition map (A B : Type) := A -> option B.
|
||||||
|
|
||||||
|
Definition empty A B : map A B := fun _ => None.
|
||||||
|
|
||||||
|
Section decide.
|
||||||
|
Variable P : Prop.
|
||||||
|
|
||||||
|
Lemma decided : inhabited (sum P (~P)).
|
||||||
|
Proof.
|
||||||
|
destruct (classic P).
|
||||||
|
constructor; exact (inl _ H).
|
||||||
|
constructor; exact (inr _ H).
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Definition decide : sum P (~P) :=
|
||||||
|
epsilon decided (fun _ => True).
|
||||||
|
End decide.
|
||||||
|
|
||||||
|
Definition add A B (m : map A B) (k : A) (v : B) : map A B :=
|
||||||
|
fun k' => if decide (k' = k) then Some v else m k'.
|
||||||
|
Definition join A B (m1 m2 : map A B) : map A B :=
|
||||||
|
fun k => match m1 k with
|
||||||
|
| None => m2 k
|
||||||
|
| x => x
|
||||||
|
end.
|
||||||
|
Definition lookup A B (m : map A B) (k : A) := m k.
|
||||||
|
Definition includes A B (m1 m2 : map A B) :=
|
||||||
|
forall k v, m1 k = Some v -> m2 k = Some v.
|
||||||
|
|
||||||
|
Definition dom A B (m : map A B) : set A := fun x => m x <> None.
|
||||||
|
|
||||||
|
Theorem map_ext : forall A B (m1 m2 : map A B),
|
||||||
|
(forall k, lookup m1 k = lookup m2 k)
|
||||||
|
-> m1 = m2.
|
||||||
|
Proof.
|
||||||
|
intros; extensionality k; auto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem lookup_empty : forall A B (k : A), lookup (empty B) k = None.
|
||||||
|
Proof.
|
||||||
|
auto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem includes_lookup : forall A B (m m' : map A B) k v,
|
||||||
|
lookup m k = Some v
|
||||||
|
-> includes m m'
|
||||||
|
-> lookup m' k = Some v.
|
||||||
|
Proof.
|
||||||
|
auto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem includes_add : forall A B (m m' : map A B) k v,
|
||||||
|
includes m m'
|
||||||
|
-> includes (add m k v) (add m' k v).
|
||||||
|
Proof.
|
||||||
|
unfold includes, add; intuition.
|
||||||
|
destruct (decide (k0 = k)); auto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem lookup_add_eq : forall A B (m : map A B) k v,
|
||||||
|
lookup (add m k v) k = Some v.
|
||||||
|
Proof.
|
||||||
|
unfold lookup, add; intuition.
|
||||||
|
destruct (decide (k = k)); tauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem lookup_add_ne : forall A B (m : map A B) k k' v,
|
||||||
|
k' <> k
|
||||||
|
-> lookup (add m k v) k' = lookup m k'.
|
||||||
|
Proof.
|
||||||
|
unfold lookup, add; intuition.
|
||||||
|
destruct (decide (k' = k)); intuition.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem lookup_join1 : forall A B (m1 m2 : map A B) k,
|
||||||
|
k \in dom m1
|
||||||
|
-> lookup (join m1 m2) k = lookup m1 k.
|
||||||
|
Proof.
|
||||||
|
unfold lookup, join, dom, In; intros.
|
||||||
|
destruct (m1 k); congruence.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem lookup_join2 : forall A B (m1 m2 : map A B) k,
|
||||||
|
~k \in dom m1
|
||||||
|
-> lookup (join m1 m2) k = lookup m2 k.
|
||||||
|
Proof.
|
||||||
|
unfold lookup, join, dom, In; intros.
|
||||||
|
destruct (m1 k); try congruence.
|
||||||
|
exfalso; apply H; congruence.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem join_comm : forall A B (m1 m2 : map A B),
|
||||||
|
dom m1 \cap dom m2 = {}
|
||||||
|
-> join m1 m2 = join m2 m1.
|
||||||
|
Proof.
|
||||||
|
intros; apply map_ext; unfold join, lookup; intros.
|
||||||
|
apply (f_equal (fun f => f k)) in H.
|
||||||
|
unfold dom, intersection, constant in H; simpl in H.
|
||||||
|
destruct (m1 k), (m2 k); auto.
|
||||||
|
exfalso; rewrite <- H.
|
||||||
|
intuition congruence.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem join_assoc : forall A B (m1 m2 m3 : map A B),
|
||||||
|
join (join m1 m2) m3 = join m1 (join m2 m3).
|
||||||
|
Proof.
|
||||||
|
intros; apply map_ext; unfold join, lookup; intros.
|
||||||
|
destruct (m1 k); auto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem empty_includes : forall A B (m : map A B), includes (empty (A := A) B) m.
|
||||||
|
Proof.
|
||||||
|
unfold includes, empty; intuition congruence.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem dom_empty : forall A B, dom (empty (A := A) B) = {}.
|
||||||
|
Proof.
|
||||||
|
unfold dom, empty; intros; sets idtac.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem dom_add : forall A B (m : map A B) (k : A) (v : B),
|
||||||
|
dom (add m k v) = {k} \cup dom m.
|
||||||
|
Proof.
|
||||||
|
unfold dom, add; simpl; intros.
|
||||||
|
sets ltac:(simpl in *; try match goal with
|
||||||
|
| [ _ : context[if ?E then _ else _] |- _ ] => destruct E
|
||||||
|
end; intuition congruence).
|
||||||
|
Qed.
|
||||||
|
End M.
|
||||||
|
|
||||||
|
Export M.
|
122
Relations.v
Normal file
122
Relations.v
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
Set Implicit Arguments.
|
||||||
|
|
||||||
|
|
||||||
|
Section trc.
|
||||||
|
Variable A : Type.
|
||||||
|
Variable R : A -> A -> Prop.
|
||||||
|
|
||||||
|
Inductive trc : A -> A -> Prop :=
|
||||||
|
| TrcRefl : forall x, trc x x
|
||||||
|
| TrcFront : forall x y z,
|
||||||
|
R x y
|
||||||
|
-> trc y z
|
||||||
|
-> trc x z.
|
||||||
|
|
||||||
|
Hint Constructors trc.
|
||||||
|
|
||||||
|
Theorem trc_trans : forall x y, trc x y
|
||||||
|
-> forall z, trc y z
|
||||||
|
-> trc x z.
|
||||||
|
Proof.
|
||||||
|
induction 1; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Hint Resolve trc_trans.
|
||||||
|
|
||||||
|
Inductive trcEnd : A -> A -> Prop :=
|
||||||
|
| TrcEndRefl : forall x, trcEnd x x
|
||||||
|
| TrcBack : forall x y z,
|
||||||
|
trcEnd x y
|
||||||
|
-> R y z
|
||||||
|
-> trcEnd x z.
|
||||||
|
|
||||||
|
Hint Constructors trcEnd.
|
||||||
|
|
||||||
|
Lemma TrcFront' : forall x y z,
|
||||||
|
R x y
|
||||||
|
-> trcEnd y z
|
||||||
|
-> trcEnd x z.
|
||||||
|
Proof.
|
||||||
|
induction 2; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Hint Resolve TrcFront'.
|
||||||
|
|
||||||
|
Theorem trc_trcEnd : forall x y, trc x y
|
||||||
|
-> trcEnd x y.
|
||||||
|
Proof.
|
||||||
|
induction 1; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Hint Resolve trc_trcEnd.
|
||||||
|
|
||||||
|
Lemma TrcBack' : forall x y z,
|
||||||
|
trc x y
|
||||||
|
-> R y z
|
||||||
|
-> trc x z.
|
||||||
|
Proof.
|
||||||
|
induction 1; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Hint Resolve TrcBack'.
|
||||||
|
|
||||||
|
Theorem trcEnd_trans : forall x y, trcEnd x y
|
||||||
|
-> forall z, trcEnd y z
|
||||||
|
-> trcEnd x z.
|
||||||
|
Proof.
|
||||||
|
induction 1; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Hint Resolve trcEnd_trans.
|
||||||
|
|
||||||
|
Theorem trcEnd_trc : forall x y, trcEnd x y
|
||||||
|
-> trc x y.
|
||||||
|
Proof.
|
||||||
|
induction 1; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Hint Resolve trcEnd_trc.
|
||||||
|
|
||||||
|
Inductive trcLiteral : A -> A -> Prop :=
|
||||||
|
| TrcLiteralRefl : forall x, trcLiteral x x
|
||||||
|
| TrcTrans : forall x y z, trcLiteral x y
|
||||||
|
-> trcLiteral y z
|
||||||
|
-> trcLiteral x z
|
||||||
|
| TrcInclude : forall x y, R x y
|
||||||
|
-> trcLiteral x y.
|
||||||
|
|
||||||
|
Hint Constructors trcLiteral.
|
||||||
|
|
||||||
|
Theorem trc_trcLiteral : forall x y, trc x y
|
||||||
|
-> trcLiteral x y.
|
||||||
|
Proof.
|
||||||
|
induction 1; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem trcLiteral_trc : forall x y, trcLiteral x y
|
||||||
|
-> trc x y.
|
||||||
|
Proof.
|
||||||
|
induction 1; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Hint Resolve trc_trcLiteral trcLiteral_trc.
|
||||||
|
|
||||||
|
Theorem trcEnd_trcLiteral : forall x y, trcEnd x y
|
||||||
|
-> trcLiteral x y.
|
||||||
|
Proof.
|
||||||
|
induction 1; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem trcLiteral_trcEnd : forall x y, trcLiteral x y
|
||||||
|
-> trcEnd x y.
|
||||||
|
Proof.
|
||||||
|
induction 1; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Hint Resolve trcEnd_trcLiteral trcLiteral_trcEnd.
|
||||||
|
End trc.
|
||||||
|
|
||||||
|
Notation "R ^*" := (trc R) (at level 0).
|
||||||
|
Notation "*^ R" := (trcEnd R) (at level 0).
|
||||||
|
|
||||||
|
Hint Constructors trc.
|
117
Sets.v
Normal file
117
Sets.v
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
Require Import Classical FunctionalExtensionality List.
|
||||||
|
|
||||||
|
Set Implicit Arguments.
|
||||||
|
|
||||||
|
|
||||||
|
Axiom prop_ext : forall P Q : Prop,
|
||||||
|
(P <-> Q) -> P = Q.
|
||||||
|
|
||||||
|
Section set.
|
||||||
|
Variable A : Type.
|
||||||
|
|
||||||
|
Definition set := A -> Prop.
|
||||||
|
Definition In (x : A) (s : set) := s x.
|
||||||
|
|
||||||
|
Definition constant (ls : list A) : set := fun x => List.In x ls.
|
||||||
|
Definition universe : set := fun _ => True.
|
||||||
|
Definition check (P : Prop) : set := fun _ => P.
|
||||||
|
|
||||||
|
Definition union (s1 s2 : set) : set := fun x => s1 x \/ s2 x.
|
||||||
|
Definition intersection (s1 s2 : set) : set := fun x => s1 x /\ s2 x.
|
||||||
|
Definition complement (s : set) : set := fun x => ~s x.
|
||||||
|
|
||||||
|
Definition subseteq (s1 s2 : set) := forall x, s1 x -> s2 x.
|
||||||
|
Definition subset (s1 s2 : set) := subseteq s1 s2 /\ ~subseteq s2 s1.
|
||||||
|
|
||||||
|
Definition scomp (P : A -> Prop) : set := P.
|
||||||
|
|
||||||
|
Theorem sets_equal : forall s1 s2 : set, (forall x, s1 x <-> s2 x) -> s1 = s2.
|
||||||
|
Proof.
|
||||||
|
intros.
|
||||||
|
apply functional_extensionality; intros.
|
||||||
|
apply prop_ext; auto.
|
||||||
|
Qed.
|
||||||
|
End set.
|
||||||
|
|
||||||
|
Infix "\in" := In (at level 70).
|
||||||
|
Notation "{ }" := (constant nil).
|
||||||
|
Notation "{ x1 , .. , xN }" := (constant (cons x1 (.. (cons xN nil) ..))).
|
||||||
|
Notation "[ P ]" := (check P).
|
||||||
|
Infix "\cup" := union (at level 40).
|
||||||
|
Infix "\cap" := intersection (at level 40).
|
||||||
|
Infix "\subseteq" := subseteq (at level 70).
|
||||||
|
Infix "\subset" := subset (at level 70).
|
||||||
|
Notation "[ x | P ]" := (scomp (fun x => P)).
|
||||||
|
|
||||||
|
Ltac sets' tac :=
|
||||||
|
unfold In, constant, universe, check, union, intersection, complement, subseteq, subset, scomp in *;
|
||||||
|
tauto || intuition tac.
|
||||||
|
|
||||||
|
Ltac sets tac :=
|
||||||
|
try match goal with
|
||||||
|
| [ |- @eq (set _) _ _ ] => apply sets_equal; intro; split
|
||||||
|
end; sets' tac.
|
||||||
|
|
||||||
|
|
||||||
|
(** * Some of the usual properties of set operations *)
|
||||||
|
|
||||||
|
Section properties.
|
||||||
|
Variable A : Type.
|
||||||
|
Variable x : A.
|
||||||
|
Variables s1 s2 s3 : set A.
|
||||||
|
|
||||||
|
Theorem union_comm : s1 \cup s2 = s2 \cup s1.
|
||||||
|
Proof.
|
||||||
|
sets idtac.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem union_assoc : (s1 \cup s2) \cup s3 = s1 \cup (s2 \cup s3).
|
||||||
|
Proof.
|
||||||
|
sets idtac.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem intersection_comm : s1 \cap s2 = s2 \cap s1.
|
||||||
|
Proof.
|
||||||
|
sets idtac.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem intersection_assoc : (s1 \cap s2) \cap s3 = s1 \cap (s2 \cap s3).
|
||||||
|
Proof.
|
||||||
|
sets idtac.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem not_union : complement (s1 \cup s2) = complement s1 \cap complement s2.
|
||||||
|
Proof.
|
||||||
|
sets idtac.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem not_intersection : complement (s1 \cap s2) = complement s1 \cup complement s2.
|
||||||
|
Proof.
|
||||||
|
sets idtac.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem subseteq_refl : s1 \subseteq s1.
|
||||||
|
Proof.
|
||||||
|
unfold subseteq; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem subseteq_In : s1 \subseteq s2 -> x \in s1 -> x \in s2.
|
||||||
|
Proof.
|
||||||
|
unfold subseteq, In; eauto.
|
||||||
|
Qed.
|
||||||
|
|
||||||
|
Theorem cap_split : forall (P1 P2 : A -> Prop),
|
||||||
|
(forall s, P1 s \/ P2 s)
|
||||||
|
-> s1 \cap [s | P1 s] \subseteq s2
|
||||||
|
-> s1 \cap [s | P2 s] \subseteq s3
|
||||||
|
-> s1 \subseteq (s2 \cap [s | P1 s]) \cup (s3 \cap [s | P2 s]).
|
||||||
|
Proof.
|
||||||
|
intros; sets eauto.
|
||||||
|
specialize (H x0).
|
||||||
|
specialize (H0 x0).
|
||||||
|
specialize (H1 x0).
|
||||||
|
tauto.
|
||||||
|
Qed.
|
||||||
|
End properties.
|
||||||
|
|
||||||
|
Hint Resolve subseteq_refl subseteq_In.
|
7
Var.v
Normal file
7
Var.v
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Require Import String.
|
||||||
|
|
||||||
|
|
||||||
|
Definition var := string.
|
||||||
|
Definition var_eq : forall x y : var, {x = y} + {x <> y} := string_dec.
|
||||||
|
|
||||||
|
Infix "==v" := var_eq (no associativity, at level 50).
|
7
_CoqProject
Normal file
7
_CoqProject
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
-R . Frap
|
||||||
|
Map.v
|
||||||
|
Var.v
|
||||||
|
Sets.v
|
||||||
|
Relations.v
|
||||||
|
Frap.v
|
||||||
|
BasicSyntax.v
|
Loading…
Reference in a new issue