2013年12月2日月曜日

Ruby-Prologについてのメモ

Prologをほとんど知らない私がRuby-Prologを使ってみたメモ。

まずは基本的な使い方。

require "ruby-prolog"
c = RubyProlog::Core.new

c.parent["Ieyasu", "Hidetada"].fact
c.parent["Hidetada", "Iemitsu"].fact
c.grandpa[:X, :Y] << [c.parent[:X, :Z], c.parent[:Z, :Y]]

p c.query(c.grandpa[:X, :Y])
#=> [[grandpa["Ieyasu", "Iemitsu"]]


いちいちc.って書くのが面倒なときはinstance_evalを利用する。irbで試すときはc.ってつけて一行ずつ処理した方が分かりやすい。

c.instance_eval do
  parent["Ieyasu", "Hidetada"].fact
  parent["Hidetada", "Iemitsu"].fact
  grandpa[:X, :Y] << [parent[:X, :Z], parent[:Z, :Y]]
  query grandpa[:X, :Y]
end


queryメソッドは内部的にresolveメソッドを呼び出している。resolveメソッドの挙動について調べる。

c.resolve(c.parent[:X, :Y]){|env| p env[:X]}
#=> "Hidetada"
"Iemitsu"

c.resolve(c.parent[:X, :Y]){|env| p env["Ieyasu"]}
#=> "Ieyasu"
"Ieyasu"

c.resolve(c.parent[:X, "Iemitsu"]){|env| p env[:X]}
#=> "Hidetada"

c.resolve(c.grandpa[:X, "Iemitsu"]){|env| p env[:X]}
#=> "Ieyasu"


要するに、与えた式が成り立つ状況をリストアップしてブロックを実行する。状況はenvという変数でブロックに渡され、env[:X]のようにしてその状況における変数:Xの値を調べることができる。env["Ieyasu"]のようにシンボル以外の引数を渡したときには引数がそのまま戻ってくる。


2013年6月28日金曜日

LaTeXで概念構造を書くためのマクロ

LaTeXで概念構造を書くためのマクロ。

プリアンブルで以下のように書く。
\makeatletter
\def\jcat#1{\vbox{\hbox{$_\textrm{\rm\scriptsize\mathstrut#1}$}\hrule height 0pt}}
\def\jlist#1{\vbox{\@for\i:=#1\do{\hbox{$\mathstrut$\textsc{\i}}}\hrule height 0pt}}
\def\jarg#1#2{$\left[\vcenter{\hbox{\jcat{#1} \jlist{#2}}}\right]$}
\def\jfunc#1#2{#1$\left(\vcenter{\hbox{#2}}\right)$}
\makeatother
使い方
\jarg{Object}{car,red}

\jfunc{have}{John, car}

\jarg{Event}{\jfunc{have}{\jarg{Object}{John},\jarg{Object}{car,\jarg{Property}{red}}}}
結果
ポイント

  • かっこは数式モードの\left[や\right]などで書く。
  • かっこのすぐ内側には\vcenterを置く。
    • ( )の内側は\vboxでもいいかも。
  • \vcenterや\vboxの内側には\hboxと\hruleのみ置く。
    • vbox系は内部のhboxの幅に応じて自動的に横幅が決まる。
    • hboxを置かずに直接文字などを置くと横幅が行幅いっぱいに広がる。
  • \vbox内の最後には高さ0の\hruleを置く。
    • ベースラインをそろえるため。
    • 高さ0にするのは不可視にするため。
  • 文字列を置く可能性のある場所には$\mathstrut$を置く。
    • 行高を確保してレイアウト崩れを防ぐ。