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

JOI夏季セミナー2018 発表資料

shibh308
August 19, 2018

JOI夏季セミナー2018 発表資料

2018年JOI夏季セミナー 型システム班三人目の発表資料です

shibh308

August 19, 2018
Tweet

More Decks by shibh308

Other Decks in Programming

Transcript

  1. 2   はじめに • このスライドでは静的型付けでラムダ計算を実装した話を書きます • 頭のいい感じの数学や理論っぽい事は ( 多分 )

    やりません • 前二つの発表の内容を前提として説明してる部分があります • … 本の内容に対する理解が浅いので間違っている所があるかもしれません • 内容はあまり面白くないです ごめんなさい • この次の発表がこれの上位互換になっているので、それの前座になります
  2. 7   言語全体の仕様について • 型付きでラムダ計算を実行できるようにする • 基本的な部分は型無しの場合とあまり変わらない • プリミティブな型として bool(B)

    と nat(N) を扱えるようにする • タプルを実装して、それを引数にとった四則演算も組み込みで用意する • ラムダ抽象の記号は @ で、 @ 名前 : 引数の型 .( 処理 ) のように書く • $ 名前 ( 処理 ) でいい感じの宣言ができる $v(5) (@x:N.add (3, x)) v のように記述できる
  3. 8   実装について • C++17 でゴリゴリ書いていく (std::variant を使うため ) •

    入出力の部分は実装が辛いのでそこは C++ に投げる • パースや型検査時のエラーは箇所や内容を表示させる せっかく静的に付けてるのでここはちゃんとやりたい
  4. 10   構文解析について • std::string で受け取った文章を気合でパースする • 仕様に沿って構文木のノードを生成して、子を shared_ptr で持つ

    • 問題が発生した場合は parseError を吐いて終了させる • 解析した結果は json 形式で出力して可視化できるようにした • すごい面倒 ツール使わずにやるものじゃないです
  5. 11   型検査について • 構文解析後に変数の型 (bool,int 等 ) が正しいかを DFS

    で調べる • 検査時点で型が定まっていない場合も子を再帰的に見る • tuple の場合は tuple 内の型が全て正しいかを検査する • 型が正しくなかったらエラーを吐いて終了させる • これをするとランタイムエラーがすごい減る うれしい
  6. 12   実行について • なんとなく簡約をしてから評価をしたくなるので仮にそうする • まラムダ抽象に対する関数適用か let 束縛をするノードを探す •

    その後、その名前とマッチしている部分を置き換える DFS をする • あとは関数適用を評価していけばそれで演算結果が取得できる (@x:T.expr) v を [x->v](expr) にする
  7. 13   実際の実装について • 構文木のノードはクラスとして実装する   ・構文の形式 ( 抽象 ,

    適用とか )   ・返り値の型 ( 型検査の時に用いる )   ・構文本体の内容   ・子ノードの shared_ptr の配列                   とかを持つ事にする • “15” ならこれらの内容は { 値 ,nat,15,{}} とかになる
  8. 14   実際の実装について • 構文木の生成時には返り値が決まっていない時がある ( 適用など ) • その場合は型検査の時に子ノードから返り値の型を決定する

    • 例 : “succ 1” ” は succ” ” と 1” を子に持つノード       →  返り値の型がまだ決まっていない 型検査時に型を決定する     succ は nat を引数にして nat を返す関数         →” succ 1” の返り値は nat になる
  9. 15   実際の実装について • 組み込みの関数 ( 四則演算など ) をいちいち特別処理するのは厳しい  

    →組み込み関数の設定を簡単にできるようにしよう! • 組み込み関数の定義に必要なパラメータをまとめる構造体を作った   ・名前   ・引数の型   ・返り値の型   ← ・関数本体 型の取りうる値が複数ある std::function<hoge(fuga)>
  10. 16   実際の実装について • 組み込みの関数 ( 四則演算など ) をいちいち特別処理するのは厳しい  

    →組み込み関数の設定を簡単にできるようにしよう! • 組み込み関数の定義に必要なパラメータをまとめる構造体を作った   ・名前   ・引数の型   ・返り値の型   ←   ← ・関数本体 型の取りうる値が複数ある variant で殴ろう! std::function<hoge(fuga)>
  11. 17   関数の実装について • 組み込み関数を表す構造体Primitive は   Primitive( 関数名 ,

    引数の型 , 返り値の型 , 関数 ) で宣言できる • Primitive の第四引数には を指定する!!!!!! std::variant<std::function<void(std::variant<int,bool>&)>, std::function<void(std::vecto
  12. 23   オンラインジャッジでの C++17 対応 • この機会に各サイトで C++17 が使えるか調べた •

    AtCoder: 不可 • AOJ: 不可 • Codeforces: 可 • CSA: 不可 • yukicoder: 可
  13. 24   提出してみた • yukicoder なら動く事が分かったので、 ( 他の問題を ) やってみる

    • “add (div (b, a), tonat (any (mod (b, a))))" で解けそうなのがあった
  14. 25   提出してみた • yukicoder なら動く事が分かったので、 ( 他の問題を ) やってみる

    • 提出して AC できた! (https://yukicoder.me/submissions/278956)