Skip to content

Instantly share code, notes, and snippets.

@mathink
Created November 12, 2015 08:57
Show Gist options
  • Select an option

  • Save mathink/5453c1840bd47d0e68a1 to your computer and use it in GitHub Desktop.

Select an option

Save mathink/5453c1840bd47d0e68a1 to your computer and use it in GitHub Desktop.
モナド、命題、証明、交わり半束
Set Implicit Arguments.
Unset Strict Implicit.
Require Import Setoids.Setoid Morphisms.
Generalizable All Variables.
Class Setoid :=
{
carrier: Type;
equal: carrier -> carrier -> Prop;
prf_Setoid: Equivalence equal
}.
Coercion carrier: Setoid >-> Sortclass.
Coercion prf_Setoid: Setoid >-> Equivalence.
Existing Instance prf_Setoid.
Notation "(== :> X )" := (equal (Setoid:=X)).
Notation "(==)" := (==:>_).
Notation "x == y :> X" := (equal (Setoid:=X) x y) (at level 90, no associativity).
Notation "x == y" := (equal x y) (at level 90, no associativity).
Class Map (X Y: Setoid) :=
{
map: X -> Y;
substitute: Proper ((==) ==> (==)) map
}.
Coercion map: Map >-> Funclass.
Existing Instance substitute.
Instance Map_setoid (X Y: Setoid): Setoid :=
{
carrier := Map X Y;
equal f g := forall x, f x == g x
}.
Proof.
split.
- intros f x; reflexivity.
- intros f g Heq x; symmetry; apply Heq.
- intros f g h H H' x; transitivity (g x); [apply H | apply H'].
Defined.
Instance Map_comp {X Y Z: Setoid}(f: Map X Y)(g: Map Y Z): Map X Z :=
{
map x := g (f x)
}.
Proof.
intros x y Heq; repeat apply substitute; auto.
Defined.
Instance Map_id (X: Setoid): Map X X :=
{
map x := x
}.
Proof.
intros x y Heq; auto.
Defined.
Class Category :=
{
obj: Type;
hom: obj -> obj -> Setoid;
comp: forall {X Y Z: obj}, hom X Y -> hom Y Z -> hom X Z;
id: forall (X: obj), hom X X;
comp_subst:
forall (X Y Z: obj)(f f': hom X Y)(g g': hom Y Z),
f == f' -> g == g' -> comp f g == comp f' g';
comp_assoc:
forall {X Y Z W: obj}(f: hom X Y)(g: hom Y Z)(h: hom Z W),
comp f (comp g h) == comp (comp f g) h;
comp_id_dom:
forall {X Y: obj}(f: hom X Y),
comp (id X) f == f;
comp_id_cod:
forall {X Y: obj}(f: hom X Y),
comp f (id Y) == f
}.
Coercion obj: Category >-> Sortclass.
Coercion hom: Category >-> Funclass.
Notation "g \o{ C } f" := (comp (Category:=C) f g) (at level 60, right associativity).
Notation "g \o f" := (g \o{_} f) (at level 60, right associativity).
Notation "'Id' X" := (id X) (at level 60, right associativity).
Class Kleisli (C: Category)(T: C -> C) :=
{
pure: forall {X: C}, C X (T X);
bind: forall {X Y: C}, C X (T Y) -> C (T X) (T Y);
bind_pure:
forall {X: C},
bind (pure (X:=X)) == id (T X);
pure_bind:
forall {X Y: C}(f: hom X (T Y)),
bind f \o pure == f;
bind_bind:
forall {X Y Z: C}(f: hom X (T Y))(g: hom Y (T Z)),
bind g \o bind f == bind (bind g \o f)
}.
Class SemiLattice :=
{
sl_setoid: Setoid;
sl_binop: sl_setoid -> sl_setoid -> sl_setoid;
sl_binop_subst: Proper ((==) ==> (==) ==> (==)) sl_binop;
sl_binop_refl:
forall (x: sl_setoid),
sl_binop x x == x;
sl_binop_comm:
forall (x y: sl_setoid),
sl_binop x y == sl_binop y x;
sl_binop_assoc:
forall (x y z: sl_setoid),
sl_binop x (sl_binop y z) == sl_binop (sl_binop x y) z
}.
Coercion sl_setoid: SemiLattice >-> Setoid.
Existing Instance sl_binop_subst.
Class SLMap (A B: SemiLattice) :=
{
slmap: Map A B;
slmap_binop:
forall (x y: A),
slmap (sl_binop x y) == sl_binop (slmap x) (slmap y)
}.
Coercion slmap: SLMap >-> Map.
Existing Instance slmap.
Instance SLMap_setoid (A B: SemiLattice): Setoid :=
{
carrier := SLMap A B;
equal f g := equal (Setoid:=Map_setoid A B) f g
}.
Proof.
split.
- intros f x; reflexivity.
- intros f g Heq x; symmetry; apply Heq.
- intros f g h H H' x; transitivity (g x); [apply H | apply H'].
Defined.
Instance SLMap_comp
{A B C: SemiLattice}(f: SLMap A B)(g: SLMap B C): SLMap A C :=
{
slmap := Map_comp f g
}.
Proof.
simpl; intros.
repeat rewrite slmap_binop.
reflexivity.
Defined.
Instance SLMap_id (A: SemiLattice): SLMap _ _ :=
{
slmap := Map_id A
}.
Proof.
simpl; intros; reflexivity.
Defined.
Instance SL: Category :=
{
obj := SemiLattice;
hom := SLMap_setoid;
comp := @SLMap_comp;
id := SLMap_id
}.
Proof.
- simpl; intros.
rewrite (H x), (H0).
reflexivity.
- simpl; intros; reflexivity.
- simpl; intros; reflexivity.
- simpl; intros; reflexivity.
Defined.
Class KPL (C: Category)(T: C -> C)(K: Kleisli T)(pred: C -> SL) :=
{
sbst: forall {X Y: C}, C X (T Y) -> SL (pred Y) (pred X);
sbst_subst: forall (X Y: C), Proper ((==) ==> (==)) (@sbst X Y);
sbst_comp:
forall (X Y Z: C)(f: hom X (T Y))(g: hom Y (T Z)),
sbst f \o sbst g == sbst (bind g \o f);
sbst_id:
forall (X: C),
sbst (pure (X:=X)) == id (pred X)
}.
Existing Instance sbst_subst.
Instance function (X Y: Type): Setoid :=
{
carrier := X -> Y;
equal f g := forall x, f x = g x
}.
Proof.
split.
- intros f x; auto.
- intros f g Heq x; auto.
- intros f g h Heqfg Heqgh x.
rewrite Heqfg; apply Heqgh.
Defined.
Instance Types: Category :=
{
obj := Type;
hom X Y := function X Y;
comp X Y Z f g x := g (f x);
id X x := x
}.
Proof.
- simpl; intros.
rewrite H, H0; auto.
- simpl; intros; auto.
- simpl; intros; auto.
- simpl; intros; auto.
Defined.
Instance Maybe: Kleisli (C:=Types) option :=
{
pure X x := Some x;
bind X Y f m := match m with Some x => f x | _ => None end
}.
Proof.
- simpl; intros X [x|]; auto.
- simpl; intros X Y f x; auto.
- simpl; intros X Y Z f g [x|]; auto.
Defined.
Module Pred.
Definition type (X: Type) := X -> Prop.
Definition pord {X: Type}(P Q: type X) := forall x, P x -> Q x.
Arguments pord {X}(P Q) /.
Definition impl {X: Type}(P Q: type X) := fun x => P x -> Q x.
Arguments impl {X}(P Q) x /.
Definition not {X: Type}(P: type X) := fun x => ~ P x.
Arguments not {X}(P) x /.
Definition and {X: Type}(P Q: type X) := fun x => P x /\ Q x.
Arguments and {X}(P Q) x /.
Definition or {X: Type}(P Q: type X) := fun x => P x \/ Q x.
Arguments or {X}(P Q) x /.
Definition True := fun {X: Type}(_: X) => True.
Definition False := fun {X: Type}(_: X) => False.
End Pred.
Notation predicate := Pred.type.
Instance Pred_setoid (X: Type): Setoid :=
{
carrier := predicate X;
equal P Q := forall x, P x <-> Q x
}.
Proof.
split.
- intros P x; tauto.
- intros P Q H; symmetry; auto.
- intros P Q R H H' x; transitivity (Q x); auto.
Defined.
Instance Pred_SL (X: Type): SemiLattice :=
{
sl_setoid := Pred_setoid X;
sl_binop := Pred.and (X:=X)
}.
Proof.
- simpl; intros P P' Hp Q Q' Hq x; simpl.
rewrite Hp, Hq.
tauto.
- simpl; tauto.
- simpl; tauto.
- simpl; tauto.
Defined.
Inductive Preds :=
| preds (X: Type)(P: predicate X).
Definition base (p: Preds) := match p with preds x _ => x end.
Definition pr (p: Preds): predicate (base p) := match p with preds _ x => x end.
Coercion pr: Preds >-> predicate.
Instance Monotone (P Q: Preds): Setoid := function (base P) (base Q).
Instance PoSets: Category :=
{
obj := Preds;
hom P Q := Monotone P Q;
comp X Y Z f g := g \o f;
id P := id (base P)
}.
Proof.
- simpl; intros.
rewrite H, H0; auto.
- simpl; intros; auto.
- simpl; intros; auto.
- simpl; intros; auto.
Defined.
Program Instance MaybeKPL: KPL Maybe (fun X: Type => Pred_SL X) :=
{
sbst X Y f :=
{|
slmap :=
{|
map := fun P x => match f x with Some y => P y | _ => False end
|}
|}
}.
Next Obligation.
simpl; intros P Q H x.
destruct (f x) as [y|]; auto.
split; auto.
Qed.
Next Obligation.
rename x into P, y into Q, x0 into x.
destruct (f x) as [y|]; tauto.
Qed.
Next Obligation.
intros f g H Q x; simpl.
rewrite <- H.
destruct (f x) as [y|]; tauto.
Qed.
Next Obligation.
rename x into R, x0 into x.
destruct (f x) as [y|]; tauto.
Qed.
Next Obligation.
tauto.
Qed.
Notation "m >>= f" := (bind (C:=Types) f m) (at level 53, left associativity).
Notation "x <- m ; p" := (m >>= fun x => p) (at level 60, right associativity).
Notation "x <-: m ; p" := (x <- pure m ; p ) (at level 60, right associativity).
Notation "f # P " := (sbst (C:=Types) f P) (at level 45, right associativity).
Notation "f >> g" := (bind (C:=Types) g \o{Types} f) (at level 42, right associativity).
Notation "P -=> Q" := (Pred.pord P Q) (at level 70, no associativity).
Notation "[ x <~ P ] ; m ; [ y ~> Q ]" := ((fun x => P) -=> (fun x => x <- m; pure x) # (fun y => Q)) (at level 95).
Notation "'for' x 'with' P ; 'result' y 'of' m ; 'satisfies' Q" := ([x<~P];m;[y~>Q]) (at level 95).
Require Import Arith.
Fixpoint dif (n m: nat){struct m} :=
match n, m with
| S n', S m' => dif n' m'
| _, 0 => Some n
| 0, S _ => None
end.
(* success *)
Goal
forall n,
for x with x = S n;
result z of
(y <-: (S x);
dif y 2);
satisfies z = n.
Proof.
simpl; intros; subst.
destruct n; ring.
Qed.
Lemma le_ind':
forall (P : nat -> nat -> Prop),
(forall n, P 0 n) ->
(forall n m : nat, P n m -> P (S n) (S m)) ->
forall n m : nat, le n m -> P n m.
Proof.
intros.
revert m H1; induction n.
- intros; apply H.
- destruct m.
+ intro H1; inversion H1.
+ intro Hle; apply H0, IHn, le_S_n; auto.
Qed.
Require Import Omega.
Goal
for x with (2 <= x);
result z of
(mx <-: x * x;
px <-: x + x;
pure (px, mx));
satisfies let (px,mx) := z in px <= mx.
Proof.
simpl.
intros.
elim H; simpl; auto.
intros.
rewrite plus_comm; simpl.
rewrite mult_comm; simpl.
omega.
Qed.
Goal
for nm with (let (n,m) := nm:nat*nat in n <= m);
result z of (let (n,m) := nm:nat*nat in dif m n);
satisfies 0 <= z.
Proof.
simpl; intros [n m] Hle; simpl in *.
pattern n, m; apply le_ind'; auto; clear Hle n m.
destruct n; simpl; auto with arith.
Qed.
Lemma hcomp:
forall {X Y Z: Type}(P: predicate X)(Q: predicate Y)(R: predicate Z)
(f: X -> option Y)(g: Y -> option Z),
(for x with P x; result y of f x; satisfies Q y) ->
(for y with Q y; result z of g y; satisfies R z) ->
(for x with P x; result z of y <- f x; g y; satisfies R z).
Proof.
simpl; intros.
generalize (H _ H1); destruct (f x) as [y|]; auto; intros.
generalize (H0 _ H2); destruct (g y) as [z|]; auto.
Qed.
Goal
for x with 2 <= x;
result z of
(mx <-: x * x;
px <-: x + x;
dif mx px);
satisfies 0 <= z.
Proof.
change
(for x with 2 <= x;
result z of
(mx <-: x * x;
px <-: x + x;
pm <-: (px,mx); (* intermediate parameter *)
let (p,m) := pm:_*_ in dif m p);
satisfies 0 <= z).
eapply hcomp.
- apply Unnamed_thm0.
- apply Unnamed_thm1.
Qed.
(* failure *)
Goal
forall P,
~ (for x with x = 0;
result _ of y <-: (S x); dif y 2;
satisfies P).
Proof.
simpl; intros P H; generalize (H _ (eq_refl _)); simpl; auto.
Qed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment