LoginSignup
3
0

More than 1 year has passed since last update.

prologで四則演算とJavaScriptの文字列足し算を実装とかを書いてみる。

Last updated at Posted at 2021-12-04

Prologは言語実装の実験するのに最高なので四則演算のインタプリタを作ってみますよ。

モチベーション

なんか、youtubeの放送を見てて唐突にやる気が出た。面白いのだけど、低レイヤー勢にもPrologを使ってほしいと思ったんです。はい。
自作ブラウザを拡張する作業配信 - JavaScriptインタプリタをつくる #low_layer_girls

SWI-Prolog インストール

brew install swi-prolog
apt install swi-prolog

などでインストールできます。

構文:

e ::= i | e+e | e-e | e*e | e/e. % 式
v ::= i. % 値

評価規則と実行

eval.pl
eval(I,I):-integer(I),!.
eval(E1+E2,I):- eval(E1,I1),eval(E2,I2), I is I1+I2.
eval(E1-E2,I):- eval(E1,I1),eval(E2,I2), I is I1-I2.
eval(E1*E2,I):- eval(E1,I1),eval(E2,I2), I is I1*I2.
eval(E1/E2,I):- eval(E1,I1),eval(E2,I2), I is I1 div I2.
:- eval(1+2+3+4,R),writeln(R),R=10.
:- halt.

実行してみます。

$ swipl eval.pl
10

評価規則と実行(2)

PrologのアトムはLispのシンボルみたいなもので、JavaScriptの文字列の代わりにアトムを使って足し算の規則を追加してみたいと思います。

eval.pl
eval(I,I):-integer(I),!.
eval(X,X):-atom(X),!.
eval(E1+E2,I):- eval(E1,I1),eval(E2,I2),!,
    (integer(I1),integer(I2)->I is I1+I2;format(atom(I),'~w~w',[I1,I2])).
eval(E1-E2,I):- eval(E1,I1),eval(E2,I2),I is I1-I2.
eval(E1*E2,I):- eval(E1,I1),eval(E2,I2),I is I1*I2.
eval(E1/E2,I):- eval(E1,I1),eval(E2,I2),I is I1 div I2.
:- eval('12'+34,R),writeln(R),R='1234'.
:- eval(12+34,R),writeln(R),R=46.
:- halt.

実行してみます:

$ swipl eval.pl
1234
46

できましたー。以上です。

バックトラック使ってさらに美しく

eval.pl
eval(E1+E2,I):- eval(E1,I1),eval(E2,I2),!,
    (integer(I1),integer(I2)->I is I1+I2;format(atom(I),'~w~w',[I1,I2])).

の規則はバックトラックを使うと以下のように分けてかけます:

eval.pl
eval(E1+E2,I):- eval(E1,I1),eval(E2,I2),integer(I1),integer(I2),I is I1+I2.
eval(E1+E2,X):- eval(E1,V1),eval(E2,V2),format(atom(X),'~w~w',[V1,V2]).

こちらの規則の方が美しいですが、遅くなります。
美しいものには棘があるわけですよ。

まとめ

さらっとPrologでJavaScriptっぽい四則演算の処理を書いてみました。慣れれば、5分くらいで書けると思うのでLTでサクッと書いてみてはいかがでしょうか?

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0