我正在寻找方法使Prolog程序“看起来”更像是第一顺序逻辑。我想要的东西是例如:
或者是否有其他软件已经实现了这一点?
提前致谢!
/ JC
更新20190313我按照下面的答案中的建议并尝试了这个:
:- op(1200, xfx, ==>).
:- op(1000, xfy, /\).
:- op(1100, xfy, \/).
term_expansion(A ==> B, B:- A).
term_expansion(A /\ B, A, B).
term_expansion(A \/ B, A; B).
man(X) /\ unmarried(X) ==> bachelor(X).
man(john).
man(peter).
unmarried(john).
main:-bachelor(X), writeln(X), nl, fail.
但是我收到以下错误:
ERROR: bachelor/1: Undefined procedure: (/\)/2
Exception: (5) man(_1740)/\unmarried(_1740) ?
然而,仅使用op / 3和term_expansion / 3 for ==>按预期工作。不知道为什么会这样......
此答案涉及您更新的问题(“更新20190313”)。
定义运算符时要小心:
(\/)/2
为例。
它是算术表达式中可评估的函子 - 与(is)/2
,(=:=)/2
,(<)/2
等一起使用。
clpfd用它来表示像1..3 \/ 5..7
-fine这样的集合联盟!
但是,使用它来表示列表连接是值得怀疑的。让我们来看看你的实际问题!
考虑使用(=..)/2
(“univ”)分解一些术语的这些查询:
?- term_expansion(A /\ B, A, B) =.. Xs.
Xs = [term_expansion, A/\B, A, B].
?- term_expansion(A \/ B, A; B) =.. Xs.
Xs = [term_expansion, A\/B, (A;B)].
所以这是term_expansion/2
的(\/)/2
,但term_expansion/3
为(/\)/2
!
底线:(',')/2
术语作为参数需要括号。
?- term_expansion(A /\ B, (A,B)) =.. Xs. Xs = [term_expansion, A/\B, (A,B)].
在SWI-Prolog上使用term_expansion / 2是Prolog的宏:
% calc.pl
:- op(1200,xfx,--).
term_expansion(A--B,B:-A).
integer(I)
--%----------------------- (E-Int)
I => I.
E1=>I1, E2=>I2, I is I1+I2
--%----------------------- (E-Add)
E1+E2 => I.
:- 1+2+3=>6.
:- 1+2+3=>I,writeln(I).
:- halt.
并运行
$ swipl calc.pl
6
以下是一些可以帮助您的Unicode字符:
¬ → ⇒ ← ⇐ ∨ ∧ ∀ ∃
我使用op/3
将合适的优先级定义为挑战。
一旦有了这些定义,就可以用它们编写一阶句子。然后,您可以将这些句子转换为Prolog,或者使用Prolog解释它们。