ゆとりが数週間でC++を
  始めるようです
  えりっく さーとる
すみません
 数週間も
やってないです
ゆとりが数日間でC++を
  始めるようです
  えりっく さーとる
ゆとりが数日間でC++を
         始めるようです
•    えりっく さーとる(@siritori)
•    ここの情報科学類2年生
•    C++わかんない
•    論理やったり(Alloy)
•    分散しようとしたり(Erlang)
•    自然言語処理しようとしたり
•    こういうタイトルで発表するのって
     どうかと思いますよねorz
ゆとりが数日間でC++を
         始めるようです


•    水曜日(23日)から勉強開始
•    C++歴 : 3日
•    コケたとことか挙げてみます
•    勉強がてら作ったものとか紹介します
なんで勉強始めたの
•  Boost勉強会のためだけじゃない
•  いろいろCで書くの好きなんだけど
 –  型がガバガバで書いてて不安
 –  C99に走ったもののそろそろ我慢の限界
 –  staticでnamespace絞って
 –  関数ポインタで柔軟に書いて
 –  もう...ゴールしてもいいよね...
•  それに「C++書けます!」って
なんで勉強始めたの
•  Boost勉強会のためだけじゃない
•  いろいろCで書くの好きなんだけど
 –  型がガバガバで書いてて不安
 –  C99に走ったもののそろそろ我慢の限界
 –  staticでnamespace絞って
 –  関数ポインタで柔軟に書いて
 –  もう...ゴールしてもいいよね...
•  それに「C++書けます!」って
つらかった
 ところ
 その1
「使うな!」
  っていう仕様が大杉

   把握してるだけでも
   ・auto_ptr
   ・独立参照
   ・const_cast
   ・protected
「使うな!」
  っていう仕様が大杉

   把握してるだけでも
   ・auto_ptr
   ・独立参照
   ・const_cast
   ・protected
   お前は
   ハウルの動く城か
つらかった
 ところ
 その2
「これでもか!!」
 ってくらいの
エラーメッセージ
    ちょっと間違えた
    だけじゃん(́;ω;`)
    そりゃ、メッセー
    ジは細かいほうが
    いいけどさ...
とりあえず

•  2日で『独習C++』を読み終えた
•  『C++ Coding Standards』をさらっと
   だけ読んでわかった気になった
•  なんかいい題材無いかな...
•  JavaもどきじゃなくてちゃんとC++でき
   るなにかがいいな...
とりあえず
とりあえず
で。


•  「論理と形式化」という大学の講義のプ
   リントを偶然発見。
•  ふと証明木に目が行く。

• うん。これ書こう。
で。


•  「論理と形式化」という大学の講義のプ
   リントを偶然発見。
•  ふと証明木に目が行く。

• うん。これ書こう。
自然演繹法(Natural Deduction)?
自然演繹法(Natural Deduction)?

•  すみません調子乗りました
•  9つの規則に基づく証明理論の手法
•  プログラミング言語の型システムとかはこ
   れで論じるとわかりやすいんだとか
•  命題論理に対応する自然演繹の体系NKを
   実装する。
•  ※ガチ勢じゃないのであんまり突っ込ま
   ないで下さい(́・ω:;.:...
証明木の例




  こやつを証明したい
      とする

A∧B⇒B∧A
証明木の例

          仮定aからB Aが導け
          ればOK

[a:A∧B]	


⊃I,a	
         A∧B⇒B∧A
証明木の例

                   A BなんだからBは成
                   り立つよね

        [a:A∧B]	
∧E2	
           B	
        ⊃I,a	
                 A∧B⇒B∧A
証明木の例

A BなんだからAは成
り立つよね

          [a:A∧B]	
 [a:A∧B]	
  ∧E2	
            ∧E   1	

             B	
       A	
          ⊃I,a	
                   A∧B⇒B∧A
証明木の例


           BもAも成り立つから、
           B Aっていえるよね
   [a:A∧B]	
 [a:A∧B]	
∧E
 2	
            ∧E
              1	

          B	
        A	
 ∧I	

      ⊃I,a	
               B∧A	
             A∧B⇒B∧A
証明木の例




   [a:A∧B]	
 [a:A∧B]	
∧E
 2	
            ∧E
              1	

          B	
        A	
 ∧I	

      ⊃I,a	
               B∧A	
             A∧B⇒B∧A
で、なにをつくるの


•  ゴールと仮定があって、それに規則を適用
   する感じのsomethingをつくる
•  Coqの超絶劣化版
•  自動証明器まではさすがにぼくの技量と時
   間ではどうしようもありませんでしたorz
設計

•  命題を表すPropクラス
•  証明を表すTheoremクラス
•  規則たちをまとめたnamespace, Rule
•  PropもTheoremも挿入子(<<)が使えるよ
   うに書く
•  Theoremは仮定と結論からなる
•  仮定が無しで結論が言えたらQ.E.D
Prop

class	 Prop	 {

public:

	 	 	 virtual	 PropType	 type()	 const	 =	 0;

	 	 	 friend	 ostream	 &operator<<(ostream	 &stream,	 const	 Prop	 *p)	 {

	 	 	 	 	 	 return	 p->print(stream);

	 	 	 }	 	 	 

private:

	 	 	 virtual	 ostream	 &print(ostream	 &stream)	 const	 =	 0;

};
Prop
OrProp	 :	 public	 Prop	 {

	 	 	 const	 Prop	 *lp_;

	 	 	 const	 Prop	 *rp_;

public:

	 	 	 explicit	 OrProp(const	 Prop	 *lp,	 const	 Prop	 *rp):lp_(lp),rp_(rp){}

private:

	 	 	 ostream	 &print(ostream	 &stream)	 const	 {

	 	 	 	 	 	 if(OR	 >=	 lp_->type())	 stream	 <<	 "("	 <<	 lp_	 <<	 ")";

	 	 	 	 	 	 else	 stream	 <<	 lp_;

	 	 	 	 	 	 stream	 <<	 "	 ∨	 ";

	 	 	 	 	 	 if(OR	 >	 	 rp_->type())	 stream	 <<	 "("	 <<	 rp_	 <<	 ")";

	 	 	 	 	 	 else	 stream	 <<	 rp_;

	 	 	 	 	 	 return	 stream;

	 	 	 }	 	 	 

};
Theorem
•  ちょっと複雑なのでコード割愛
•  仮定(Asp)と結論(Con)を受け取るコンス
   トラクタ何種類か用意
 –  ハイチュウ排中律とか
 –  右と左の仮定のマージとか
 –  仮定単体とか
•  もうポインタ嫌い(́;ω;`)
Rule
•  Theoremとなにかを受け取って新しい
   Theoremを返すなにか
•  Aの証明とBの証明を受け取ってA Bとい
   う結論の証明を返す
   Theorem *and_intro(Theorem *t1,
   Theorem *t2)
   とかいうの書きました
で、どんなのできたの
Theorem	 *a	 =	 new	 Theorem(

	 	 	 new	 AndProp(

	 	 	 	 	 	 new	 AtomicProp('A'),	 new	 AtomicProp('B')

	 	 	 ),'a');

cout	 <<	 a	 <<	 endl;

Theorem	 *t1	 =	 Rule::and_elim2(a);

cout	 <<	 t1	 <<	 endl;

Theorem	 *t2	 =	 Rule::and_elim1(a);

cout	 <<	 t2	 <<	 endl;

Theorem	 *t3	 =	 Rule::and_intro(t1,	 t2);

cout	 <<	 t3	 <<	 endl;

Theorem	 *con	 =	 Rule::implication_intro(t3,	 'a');

cout	 <<	 con	 <<	 endl;
で、どんなのできたの
Theorem	 *a	 =	 new	 Theorem(

	 	 	 new	 AndProp(

	 	 	 	 	 	 new	 AtomicProp('A'),	 new	 AtomicProp('B')

	 	 	 ),'a');

cout	 <<	 a	 <<	 endl;

Theorem	 *t1	 =	 Rule::and_elim2(a);

cout	 <<	 t1	 <<	 endl;

                                 [a : A B]をつくる
Theorem	 *t2	 =	 Rule::and_elim1(a);

cout	 <<	 t2	 <<	 endl;

Theorem	 *t3	 =	 Rule::and_intro(t1,	 t2);

cout	 <<	 t3	 <<	 endl;

Theorem	 *con	 =	 Rule::implication_intro(t3,	 'a');

cout	 <<	 con	 <<	 endl;
で、どんなのできたの
Theorem	 *a	 =	 new	 Theorem(

       [a:A B]から
	 	 	 new	 AndProp(

                 BとAを導く
	 	 	 	 	 	 new	 AtomicProp('A'),	 new	 AtomicProp('B')

	 	 	 ),'a');

cout	 <<	 a	 <<	 endl;

Theorem	 *t1	 =	 Rule::and_elim2(a);

cout	 <<	 t1	 <<	 endl;

Theorem	 *t2	 =	 Rule::and_elim1(a);

cout	 <<	 t2	 <<	 endl;

Theorem	 *t3	 =	 Rule::and_intro(t1,	 t2);

cout	 <<	 t3	 <<	 endl;

Theorem	 *con	 =	 Rule::implication_intro(t3,	 'a');

cout	 <<	 con	 <<	 endl;
で、どんなのできたの
Theorem	 *a	 =	 new	 Theorem(

	 	 	 new	 AndProp(

	 	 	 	 	 	 new	 AtomicProp('A'),	 new	 AtomicProp('B')

	 	 	 ),'a');

cout	 <<	 a	 <<	 endl;

             BとAから
Theorem	 *t1	 =	 Rule::and_elim2(a);

cout	 <<	 t1	 <<	 endl;

            B Aを導く
Theorem	 *t2	 =	 Rule::and_elim1(a);

cout	 <<	 t2	 <<	 endl;

Theorem	 *t3	 =	 Rule::and_intro(t1,	 t2);

cout	 <<	 t3	 <<	 endl;

Theorem	 *con	 =	 Rule::implication_intro(t3,	 'a');

cout	 <<	 con	 <<	 endl;
で、どんなのできたの
Theorem	 *a	 =	 new	 Theorem(

	 	 	 new	 AndProp(

	 	 	 	 	 	 new	 AtomicProp('A'),	 new	 AtomicProp('B')

	 	 	 ),'a');

cout	 <<	 a	 <<	 endl;

Theorem	 *t1	 =	 Rule::and_elim2(a);

cout	 <<	 t1	 <<	 endl;

     B Aと仮定aから
Theorem	 *t2	 =	 Rule::and_elim1(a);

cout	 <<	 t2	 <<	 endl;

                              A B B Aを導く
Theorem	 *t3	 =	 Rule::and_intro(t1,	 t2);

cout	 <<	 t3	 <<	 endl;

Theorem	 *con	 =	 Rule::implication_intro(t3,	 'a');

cout	 <<	 con	 <<	 endl;
実行すると
Theorem	 *a	 =	 new	 Theorem(

	 	 	 new	 AndProp(

	 	 	 	 	 	 new	 AtomicProp('A'),	 new	 AtomicProp('B')

	 	 	 ),'a');

cout	 <<	 a	 <<	 endl;
実行すると
Theorem	 *t1	 =	 Rule::and_elim2(a);

cout	 <<	 t1	 <<	 endl;

Theorem	 *t2	 =	 Rule::and_elim1(a);

cout	 <<	 t2	 <<	 endl;
実行すると
Theorem	 *t3	 =	 Rule::and_intro(t1,	 t2);

cout	 <<	 t3	 <<	 endl;
実行すると
Theorem	 *con	 =	 

  Rule::implication_intro(t3,	 'a');

cout	 <<	 con	 <<	 endl;
仮定なしで導けた→証明完了
                                  ,.へ 	
   ___                             ム  i 	
  「 ヒ_i〉                            ゝ 〈 	
  ト ノ                           iニ(() 	
  i  {              ____           |  ヽ 	
  i  i           /__,  , ‐-\           i   } 	
  |   i         /(●)   ( ● )\       {、  λ 	
  ト‐┤.      /    (__人__)    \    ,ノ  ̄ ,! 	
  i   ゝ、_     |     ´ ̄`       | ,. '´ハ   ,! 	
 . ヽ、    `` 、,__\              /" \  ヽ/ 	
    \ノ ノ   ハ ̄r/:::r―--―/::7   ノ    / 	
        ヽ.      ヽ::〈; . '::. :' |::/   /   ,. " 	
         `ー 、    \ヽ::. ;:::|/     r'" 	
      / ̄二二二二二二二二二二二二二二二二ヽ 	
      |   |  動作確認                │| 	
      \_二二二二二二二二二二二二二二二二ノ
おぼえたこと
•  演算子オーバーロードってすごい
 –  泣きながら関数定義してたCがバカみたい
•  clang++の優しさに泣く
 –  ありがとう、キミのお陰でめげずにいられた
•  すみません... constを前置してすみません...
•  いろんな書き方ができるせいで流儀を身に
   付けるまでに結構な時間がかかりそう
•  闇の軍団の人たち優しい(何度も助けられ
   ながらお勉強しました)
で、結局のところ
Boostは使ってないの?
ご清聴ありがとう
ございました(ノ)・ω・(ヾ)
   https://gist.github.com/2782220
大々的に添削していただけるととても嬉しいです!

ゆとりが数週間でC++を始めるようです