Upgrade to Pro — share decks privately, control downloads, hide ads and more …

リフレクションのしくみをつくる

 リフレクションのしくみをつくる

SSReflectのリフレクションのしくみを理解するために、Standard Coqでつくってみた。

SUHARA Hiromichi

September 12, 2015
Tweet

More Decks by SUHARA Hiromichi

Other Decks in Programming

Transcript

  1. ͜͜Ͱ࢖͏දهʹ͍ͭͯ • ԾҾ਺ΛғΉʮʨʩʯ͸ɺͦͷҾ਺͕implicit Ͱ͋Δ͜ͱΛࣔ͢ɻলུ͠ͳ͚Ε͹ͳΒͳ͍ɻ Definition eq {T : Type} (a

    b : T) : Prop. Notation “a = b” := (eq a b). (* ࣮ࡍͷఆٛͱҟͳΔ *) • ؔ਺ͷલͷʮ@ʯ͸ɺimplicitͳҾ਺Λলུͤ ͣʹɺ༩͑Δ͜ͱΛࣔ͢ɻ eq 1 1 1 = 1 @eq nat 1 1 • Set Implicit Arguments. ͳͲ͸࢖Θͳ͍ɻ
  2. 1. ϦϑϨΫγϣϯ 1.1 SSReflect͸༗໊ʁ ΰʔϧʢલʣ λΫςΟΫ ΰʔϧʢޙʣ ɹm : nat

    ɹn : nat ɹ(ུ) ɹ============== ɹm = n apply/eqP. ɹm : nat ɹn : nat ɹ(ུ) ɹ============= ɹ(m == n) = true ɾm == n ͸ɺboolܕͷ౳ࣜͰ͋Δɻ ɾm == n ͸ɺίΞʔγϣϯʹΑͬͯɺ(m == n) = true ͕লུ͞Εͨ΋ͷɻ ɾʮapply/eqPʯɹ͸ɺ͜ͷจ຺Ͱ͸ɺʮapply (elimT eqP)ʯɹͱ͓ͳ ͡ɻ
  3. 1.4 ϦϑϨΫγϣϯͷ͘͠ΈΛͭ͘Δ •ܕʹґଘ͠ͳ͍ڞ௨෦෼ ◦ boolܕ͔Β໋୊ܕ΁ͷίΞʔγϣϯ ◦ Reflectͱͦͷิ୊ ◦ eqTypeܕ ◦

    ViewͱViewώϯτ •۩ମతͳܕʹґଘ͢Δ෦෼ ◦ 3஋࿦ཧʢUPɾOFFɾDOWNʣ ◦ bool஋౳ࣜͱLeibnizಉ஋ؔ܎ͷ౳Ձੑͷূ໌ ◦ ΧϊχΧϧɾετϥΫνϟ
  4. 2. ϦϑϨΫγϣϯͷ͘͠Έʢڞ௨෦ʣ 2.1 ίΞʔγϣϯ(Coercion) ɾboolܕ͔Β໋୊ܕ΁ͷίΞʔγϣϯɿ boolܕͷ஋ΛPropܕͷ஋ͱͯ͠ѻ͑ΔΑ͏ʹ͢ΔʢຒΊࠐΉʣɻ ɾis_trueΛදه্লུ͢Δ͜ͱͰ࣮ݱ͢Δɻ Definition is_true (x

    : bool) : Prop := (x = true). ɾCoercionίϚϯυΛ࢖༻͢Δɻ Coercion is_true : bool >-> Sortclass. Check 1 == 1 : bool. Check 1 == 1 : Prop. จ຺͔Β… Check is_true (1 == 1) : Prop. is_true ͕লུͱղऍ͞ΕΔɻ Fail Check 1 = 1 : bool. Prop͔Βbool͸ͩΊɻ
  5. 2.2 Reflectͱͦͷิ୊ʢ1/2ʣ • ໋୊Pͱbool஋b͕౳ՁͰ͋Δ͜ͱΛ໋ࣔ͢୊ɻ Inductive reflect (P : Prop) :

    bool -> Prop :=
 | ReflectT : P -> reflect P true
 | ReflectF : ~ P -> reflect P false. • ิ୊ Lemma iffP : forall {P Q : Prop} {b : bool}, reflect P b -> (P -> Q) -> (Q -> P) -> reflect Q b. Lemma idP : forall {b : bool}, reflect (bɹ= true) b. reflect b b
  6. 2.2 Reflectͱͦͷิ୊ʢ2/2ʣ Lemma ex1 (P : Prop) (b : bool)

    : reflect P b <-> (if b then P else ~ P). Proof. split. - intros H. (* -> *) case H. (* H : reflect P b *) + intros HP. (* P -> P *) apply HP. + intros HnP. (* ~ P -> ~ P *) apply HnP. - case b. (* <- *) + intro HP. (* P -> reflect P true *) apply ReflectT. apply HP. + intro HnP. (* ~ P -> reflect P false *) apply ReflectF. apply HnP. Qed. 

  7. 2.3 eqTypeܕͱʮ==ʯͷఆٛ ʢ1/3ʣ • bool஋౳͕ࣜఆٛ͞ΕɺLeibnizಉ஋ؔ܎ͱͷ౳Ձੑ͕ূ໌͞Εͨܕ Record mixin_of (T : Type)

    := EqMixin { op : T -> T -> bool; (* bool஋౳ࣜɹ*) a : forall x y :ɹT, (* ূ໌ɹ*) reflect (x = y) (op x y) }. Record eqType := EqType { sort : Type; m : mixin_of sort }.
  8. 2.3 eqTypeܕͱʮ==ʯͷఆٛ ʢ2/3ʣ op : forall (T : Type), (mixin_of

    T) -> T -> T -> bool. Definition eq_op {T : eqType} := @op (sort T) (m T). Notation "x == y" := (eq_op x y) (at level 70, no associativity). @eq_op : forall (T : eqType),(sort T)-> (sort T)-> bool. • ఆཧ Theorem eqP : forall {T : eqType} {x y : sort T}, reflect (x = y) (x == y). ʢeqTypeͷ্ͰʣLeibnizಉ஋ؔ܎(x=y)ͱɺbool஋౳ࣜ(x==y)͸ɺ౳ՁͰ͋Δɻ
  9. 2.3 eqTypeܕͱʮ==ʯͷఆٛ ʢ3/3ʣ • eqPͷূ໌ ɹCaseͰɺT͔Βূ໌ͷ෦෼ΛऔΓग़ͯ͠ɺద༻͢Δɻ Theorem eqP: forall {T:

    eqType}{x y: sort T}, reflect (x = y) (eq_op x y). Proof. intro T. case T. intros sort m x y. case m. intros op a. apply a. Qed.
  10. 2.4 Viewͱͦͷิ୊ʢώϯτʣ ɹʢ1/2ʣ • SSReflectͰʮapply/VʯͷVΛViewͱ͍͏ɻ • ΰʔϧʹV͕ద༻͞ΕΔҙຯͰ͸ʮapply Vʯͱಉ͡ɻ • Viewʹ͸ɺReflect

    P b ͷܕͷఆཧ͕࢖ΘΕΔ৔߹͕ଟ ͍ɻࠓճ͸ eqP ͷΈɻ • GoalͱV(View)ͷ૊Έ߹ΘͤͰิ୊͕ิΘΕΔɻ ɹHintͱͯ͠ొ࿥͢Δɻ ྫɿʮapply/eqPʯ͕ʮapply (elimT eqP)ʯͱΈͳ͞ΕΔɻ ࠓճ͸ɺHintʹΑΔิ଍͸Ͱ͖ͳ͍ͷͰɺώϯτͷ෦෼΋ॻ͘ɻ
  11. 2.4 Viewͱͦͷิ୊ ʢώϯτʣ ʢ2/2ʣ • View͕eqPͷͱ͖ʹɺิΘΕΔิ୊ʢώϯτʣɻ ᶃ bool஋౳͕ࣜ੒ཱ͢ΔͳΒɺLeibnizಉ஋ؔ܎͕੒ཱ͢Δɻ Lemma elimT

    :
 forall {P : Prop}{b : bool}, reflect P b -> b -> P. • elimT eqP : x == y -> x = y ᶄ Leibnizಉ஋ؔ܎͕੒ཱ͢ΔͳΒɺbool஋౳͕ࣜ੒ཱ͢Δɻ Lemma introT :
 forall {P : Prop}{b : bool}, reflect P b -> P -> b. • introT eqP : x = y -> x == y ᶅ introTFɺelimTFɺequivPif
  12. 3. ϦϑϨΫγϣϯͷ͘͠Έʢܕݻ༗෦ʣ 3.1 ྫɿupdownܕ ɾUPɺOFFɺDNͷ3஋ΛऔΔɻ Inductive updown : Set :=

    | up (* UP *) | off (* OFF *) | dn. (* DOWN *) ɾbool஋౳ࣜ Definition eqUD (x y : updown) : bool := ɹmatch x, y with | up, up => true | off, off => true | dn, dn => true | _, _ => false ɹend. Bool஋౳ࣜͷఆ͕ٛͩɺ·ͩ ʮ==ʯͰ͸࢖͑ͳ͍ɻ
  13. 3.2 updown_eqTypeܕ Λͭ͘Δ ʢeqTypeܕͷΠϯελϯεʣ ɾupdownͷbool஋౳ࣜʢeqUD)ͱɺLeibnizಉ஋ؔ܎͕ɺ౳஋Ͱ͋Δ͜ͱΛূ໌ɻ Lemma updown_eqP (x y :

    updown) : reflect (x = y) (eqUD x y). Proof. apply (iffP idP). - case x; case y; auto. (* eqUD x y -> x = y *) - case x; case y; auto. (* x = y -> eqUD x y *) Qed. ɾ updown_eqPΛ࢖ͬͯɺeqTypeܕ͔Βɺupdown_eqTypeܕΛ࡞Δɻ Definition updown_eqMixin := @EqMixin updown eqUD updown_eqP. Definition updown_eqType := @EqType updown updown_eqMixin. ɾ͔͠͠ɾɾɾ Fail Check eq_op up up. Fail Check up == up.
  14. 3.3 ΧϊχΧϧɾετϥΫνϟ ʢ1/2ʣ ɾʮ==ʯ͸ɺ3Ҿ਺ͷؔ਺ eq_op ͷୈ1Ҿ਺͕implicitʹͳͬͨ΋ͷɻ @eq_op : forall (T

    : eqType),(sort T)->(sort T)-> bool ɾୈ1Ҿ਺ʹupdown_eqTypeΛॻ͘ͱɺୈ2ୈ3Ҿ਺͕updownܕͱ൑Δɻ @eq_op updown_eqType : updown -> updown -> bool @eq_op updown_eqType up up : bool ɾ͔͠͠ɾɾɾ ୈ1Ҿ਺Λলུͨ͠৔߹ɺʮeq_op up upʯʮup == upʯ ୈ1Ҿ਺͕updown_eqTypeͰ͋Δͱ͸Θ͔Βͳ͍ɻ ɹɹT͸eqTypeܕͰ͋Δ΂͖ͱ͍͏ࢦఆ͚͔ͩΒ͸ɺupdown_eqTypeɹ͸୳ͤͳ͍ɻ ɹɹ·ͨɺsort updown_eqType ΛධՁ͢Δͱ updown ʹͳΔ͕ɺ͜Ε΋ٯ͸ٻΊΒΕͳ͍ɻ ɹɹsort ʹΑΔɺeqType͔ΒType΁ͷίΞʔγϣϯΛ༗ޮʹͯ͠΋ҧ͍͸ͳ͍ɻ
  15. 3.3 ΧϊχΧϧɾετϥΫνϟ ʢ2/2ʣ ɾͦ͜Ͱɾɾɾ ɹɹupdown_eqTypeΛeqTypeͷʮCanonical Instanceʯͱͯ͠ొ࿥͢Δɻ ɹɹCanonical Structure updown_eqType :

    eqType. ɾ͢Δͱɾɾɾ ɹɹCheck eq_op up up : bool. ɹɹCheck up == up : bool. Canonical Instance ͸ɺCanonical Structureɺ͋Δ͍͸୯ʹ Canonicalͱݺ Ϳɻ(จݙ2 p.6 ٭஫1.) ɾ·ͨɺDefinitionɹͱ·ͱΊͯ࣍ͷΑ͏ʹ΋ॻ͚Δɻ Canonical Structure updown_eqType := @EqType updown updown_eqMixin.
  16. 3.4 ϦϑϨΫγϣϯͷ࣮ߦྫ ΰʔϧʢલʣ λΫςΟΫ ΰʔϧʢޙʣ x : updown y :

    updown H : (ུ) ============== x = y apply (elimT eqP). x : updown y : updown H : (ུ) ============== x == y ΰʔϧʢલʣ λΫςΟΫ ΰʔϧʢޙʣ x : updown y : updown H : (ུ) ============== x == y apply (introT eqP). x : updown y : updown H : (ུ) ============== x = y
  17. 3.4 ʮ==ʯͷରশੑͷূ໌ʢ1/2ʣ Lemma eq_sym (x y : updown) : (x

    == y) = (y == x). Proof. apply (introTF eqP). apply (equivPif eqP); auto. Qed. ࠷ॳͷΰʔϧͷʮ=ʯͷ྆ล͸boolͰ͋Δɻ ͜ΕΛʮ<->ʯʹม׵͢Δɻಉ࣌ʹʮ==ʯΛʮ=ʯʹม׵͢Δɻ • ;ͨͭΊͷapplyͷ͋ͱͰΰʔϧ͸ɺ • x = y -> y = x • y = x -> x = y • SSReflectͷ৔߹͸ɺViewώϯτ͕࢖͑ΔͷͰɺ1ߦͰࡁΉɻ apply/eqP/eqP; auto.
  18. 3.4 ʮ==ʯͷରশੑͷূ໌ɹʢ2/2ʣ Variables (P Q : Prop) (b c :

    bool). Variables (x y : updown). Check equivPif : reflect P b -> (Q -> P) -> (P -> Q) -> (if b then Q else ~ Q). Check equivPif eqP : (x = y -> y = x) -> (y = x -> x = y) -> (if y == x then x = y else x <> y). Check introTF : reflect P b -> (if c then P else ~ P) -> b = c. Check introTF eqP : (if y == x then x = y else x <> y) -> (x == y) = (y == x).
  19. 4. ·ͱΊ 4.1 ϦϑϨΫγϣϯͷ͘͠ΈΛͭ͘Δ • ܕʹґଘ͠ͳ͍෦෼ɿ ʢ1ʣboolܕ͔Β໋୊ܕ΁ͷίΞʔγϣϯ ʢ2ʣReflectͱɺͦͷิ୊ͷূ໌ɺiffPɺidP ʢ3ʣeqTypeܕͷఆٛͱɺeq_op(==)ͷఆٛ ʢ4ʣViewͱɺͦͷิ୊ͷূ໌ɺintroTɺelimT

    • ܕʹґଘ͢Δ෦෼ɿ ʢ5ʣbool஋౳ࣜΛఆٛ͢Δɻ ʢ6ʣLeibnizಉ஋ؔ܎ͷ౳ՁੑΛূ໌͢Δɻ ʢ7ʣeqTypeܕͷΠϯελϯεΛ࡞Δɻ ʢ8ʣ ͦΕΛΧϊχΧϧɾΠϯελϯεʹ͢Δɻ
  20. 5. ࢀߟจݙɹ ʢ1/2ʣ 1. ΞϑΣϧτ Ϩφϧυ, ʮఆཧূ໌ࢧԉܥ Coq ʹΑΔܗࣜݕূʯ https://

    staff.aist.go.jp/reynald.affeldt/ssrcoq/coq-kyoto2015.pdf 2. Assia Mahboubi, Enrico Tassi, "Canonical Structures for the working Coq user“, https://hal.inria.fr/hal-00816703v1/document 3. Beta Zilian, Matthieu Sozeau, “A Unification Algorithm for COQ Featuring Universe Polymorphism and Overloading”, ICFP 2015 https://www.mpi-sws.org/~beta/papers/unicoq.pdf 4. mathink, ʮtree@SSReflectʯ http://www.mathink.net/program/ssr_tree.html
  21. 5. ࢀߟจݙɹʢ2/2ʣ 5. Georges Gonthier, Assia Mahboubi, Enrico Tassi, “A

    Small Scale Reflection Extension for the Coq system”, Nr.6455, INRIA Microsoft Research SSReflectͷΞοϓσʔτຖʹվఆ͞ΕɺϦϑΝϨϯεϚχϡΞϧͱͯ͠࢖͑Δɻ 6. Georges Gonthier, St ́phane Le Roux, “An Ssreflect Tutorial”, Nr.367, INIRA Microsoft Research 7. Georges Gonthier, Assia Mahboubi, “An introduction to small scale reflection in Coq”, Nr.7392, INIRA Microsoft Research
  22. (ิ଍1)Leibnizಉ஋ؔ܎ • Coq ͷʮ=ʯ͸྆ล͸ಉ͡΋ͷɺϢχϑΟέʔγϣϯͰ͖Δ ʢPropositional Equality)ɻ Inductive eq {A :

    Type} (x : A) : A -> Prop := eq_refl : eq A x x. Notation "a = b" := (eq a b). • Leibnizಉ஋ؔ܎ Definition leibnitz_eq (A : Type)(a b : A) : Prop := forall (P : A -> Prop), P a -> P b. • Coqͷʮ=ʯͱLeibnizಉ஋ؔ܎͸ɺ౳஋Ͱ͋Δɻ Lemma eq_leibnitz_eq : forall (A : Type) (a b : A), leibnitz_eq A a b <-> a = b.
  23. ʢิ଍3ʣViewͱViewώϯτ
 apply/View (1/3) ΰʔϧ ʢલʣ Viewͷܕ ࢖ΘΕΔ ώϯτ ΰʔϧ ʢޙʣ

    Q P<->Q iffLR P P P<->Q iffRL Q ~Q P<->Q iffLRn ~P ~P P<->Q iffRLn ~Q
  24. ʢิ଍3ʣViewͱViewώϯτ
 apply/View (2/3) ΰʔϧ ʢલʣ Viewͷܕ ࢖ΘΕΔ ώϯτ ΰʔϧ ʢޙʣ

    P reflect P b elimT b x = y reflect (x=y) (x==y) elimT x == y b reflect P b introT P x == y reflect (x=y) (x==y) introT x = y
  25. ʢิ଍3ʣViewͱViewώϯτ
 apply/View (3/3) ΰʔϧʢલʣ Viewͷܕ ࢖ΘΕΔ ώϯτ ΰʔϧʢޙʣ b =

    c reflect P b introTF if c then P else ~P if c then P else ~P reflect Q c equivPif • P -> Q • Q -> P apply/V1; apply/V2. ͸ɺ apply/V1/V2. ͱॻ͚Δɻ apply/V1/V2
  26. ʢิ଍4ʣViewͱViewώϯτ
 apply/V1/V2 (ྫ) 3.4 ͷྫͱಉ͜͡ͱΛ͓͜ͳ͏ɻ Goal forall (x y :

    updown) : (x == y) = (y == x). Proof. intros x y. apply/eqP/eqP; (* x = y -> y = x *) (* y = x -> x = y *) auto. Qed.
  27. ʢิ଍5ʣϦϑϨΫγϣϯͷ࢖༻ྫ Lemma eqn_add2l (p m n: nat) : (p +

    m == p + n) = (m == n). Proof. induction p; auto. Qed. Goal forall (p m n: nat), (p + m = p + n) -> (m = n). Proof. intros p m n H. apply (introT eqP) in H. (* H : p + m == p + n *) apply (elimT eqP). (* Goal : m == n *) rewrite <- (eqn_add2l p m n). auto. Qed.
  28. (ิ଍5)ϦϑϨΫγϣϯͷ࢖༻ྫ
 ʢࢀߟɿSSReflect൛ʣ Require Import ssreflect ssrfun ssrbool eqtype ssrnat. Lemma

    eqn_add2l p m n : (p + m == p + n) = (m == n). Proof. by elim: p. Qed. Goal forall p m n, (p + m = p + n) -> (m = n). Proof. move=> p m n. move/eqP => H. (* H : p + m == p + n *) apply/eqP. (* Goal : m == n *) by rewrite -(eqn_add2l p m n). Qed.