SWI-Prolog には、+ - * / ^ ** = == など演算子が定義されています。
ユーザーが演算子の定義をすることもできます。(Sample あり)
:- op(P,T,O).
上の「op/3」で演算子を定義します。P: 優先度, T: タイプ, O: 演算子名
オペレータータイプ一覧(T)
タイプ | 前置:中置:後置 | 結合演算 |
---|---|---|
xfx | 中置 | 結合しない |
xfy | 中置 | 右--結合 |
yfx | 中置 | 左--結合 |
fx | 前置 | 結合しない |
fy | 前置 | 右--結合 |
xf | 後置 | 結合しない |
yf | 後置 | 左--結合 |
♪ (^_^;)誰がアイスクリームを食べたのでしょうか?(^_^;)
♪ プログラムコード
code
% cat op.pl :- op(500,xfx,'tabeta'). % 中置オペレーター 結合なし taro tabeta mikan. hanako tabeta icecream.
実行例
% swipl -q ?- [op]. true. ?- taro tabeta F. F = mikan. ?- Darega tabeta icecream. Darega = hanako. ?- halt. %
SWI-Prolog に定義された演算子を呼び出してみます。
中置 結合しない
% swipl -q ?- current_op( P, xfx, O ). P = 700, O = (@>=) ; P = 700, O = (@>) ; P = 700, O = (@<) ; P = 1200, O = (-->;) ; P = 700, O = (\=@=) ; P = 700, O = (==) ; P = 700, O = (=@=) ; P = 700, O = (\=) ; P = 700, O = (=) ; P = 700, O = (<) ; P = 700, O = (@=<) ; P = 700, O = (=<) ; P = 700, O = (>) ; P = 700, O = (>=) ; P = 200, O = (**) ; P = 700, O = (=..) ; P = 700, O = (=:=) ; P = 700, O = (is) ; P = 700, O = (as) ; P = 1200, O = (:-) ; P = 700, O = (\==) ; P = 700, O = (=\=). ?- halt. %
中置 右--結合
% swipl -q ?- current_op( P, xfy, O ). P = 1000, O = (',') ; P = 600, O = (:) ; P = 1050, O = (*->) ; P = 1100, O = (;) ; P = 1050, O = (->) ; P = 1105, O = ('|') ; P = 200, O = (^). ?- halt.
中置 左--結合
% swipl -q ?- current_op( P, yfx, O ). P = 400, O = (//) ; P = 400, O = (div) ; P = 400, O = (rdiv) ; P = 400, O = (/) ; P = 400, O = (>>) ; P = 500, O = (/\) ; P = 400, O = (*) ; P = 400, O = (<< ; P = 400, O = (xor) ; P = 500, O = (\/) ; P = 400, O = (mod) ; P = 400, O = (rem) ; P = 500, O = (-) ; P = 500, O = (+). ?- halt. %
前置 結合しない
% swipl -q ?- current_op( P, fx, O ). P = 1, O = ($) ; P = 1150, O = (discontiguous) ; P = 1150, O = (thread_initialization) ; P = 1150, O = (initialization) ; P = 1150, O = (thread_local) ; P = 1150, O = (volatile) ; P = 1150, O = (multifile) ; P = 1150, O = (module_transparent) ; P = 1200, O = (:-) ; P = 1200, O = (?-) ; P = 1150, O = (dynamic) ; P = 1150, O = (public) ; P = 1150, O = (meta_predicate). ?- halt. %
前置 右--結合
% swipl -q ?- current_op( P, fy, O ). P = 200, O = (\) ; P = 900, O = (\+) ; P = 200, O = (-) ; P = 200, O = (+). ?- halt. %
後置 結合しない (なし)
% swipl -q ?- current_op( P, xf, O ). false. ?- halt. %
後置 左--結合 (なし)
% swipl -q ?- current_op( P, yf, O ). false. ?- halt. %
ここで階乗 ^ と、結合演算しない階乗 ** を実行してみます。
2^2^3 は、後ろから計算します。
2**2**3 は、結合演算しない階乗なので、エラーになります。
% swipl -q ?- current_op( P, T, ^ ). P = 200, T = xfy. % 中置 右結合 ?- current_op( P, T, ** ). P = 200, T = xfx. % 中置 結合しない ?- X is 2^3. X = 8. ?- X is 2**3. X = 8. ?- X is 2^2^3. X = 256. ?- X is 2**2**3. ERROR: Syntax error: Operator priority clash ERROR: X is 2** ERROR: ** here ** ERROR: 2**3 . ?- halt. %