ゆとりが数週間でC++を 始めるようです えりっく さーとる
Jun 28, 2015
ゆとりが数週間で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⇒B∧A
[a:A∧B]
⊃I,a
仮定aからB∧Aが導ければOK
証明木の例
A∧B⇒B∧A
B [a:A∧B]
⊃I,a
∧E2
A∧BなんだからBは成り立つよね
証明木の例
A∧B⇒B∧A
B [a:A∧B]
⊃I,a
∧E2 A
[a:A∧B] ∧E1
A∧BなんだからAは成り立つよね
証明木の例
A∧B⇒B∧A B∧A
B [a:A∧B]
⊃I,a
∧I
∧E2 A
[a:A∧B] ∧E1
BもAも成り立つから、B∧Aっていえるよね
証明木の例
A∧B⇒B∧A B∧A
B [a:A∧B]
⊃I,a
∧I
∧E2 A
[a:A∧B] ∧E1
で、なにをつくるの
• ゴールと仮定があって、それに規則を適用する感じの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; 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;
[a : A∧B]をつくる
で、どんなのできたの 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;
[a:A∧B]から BとAを導く
で、どんなのできたの 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;
BとAから B∧Aを導く
で、どんなのできたの 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;
B∧Aと仮定aから A∧B⇒B∧Aを導く
実行すると 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 大々的に添削していただけるととても嬉しいです!