我正在寻找使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用于==>,但是可以正常工作。不知道为什么会这样...
答案 0 :(得分:5)
在SWI-Prolog上使用作为Prolog宏的term_expansion / 2:
% 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
答案 1 :(得分:4)
以下一些Unicode字符可以为您提供帮助:
¬ → ⇒ ← ⇐ ∨ ∧ ∀ ∃
我将使用op/3
定义合适的优先级作为挑战。
一旦有了这些定义,就可以用它们写一阶句子。然后,您可以将这些句子转换为Prolog,或使用 Prolog对其进行解释。
答案 2 :(得分:1)
此答案指的是您更新的问题(“更新20190313”)。
在定义运算符时要小心:
不要重新定义标准运算符,更改其指定符/优先级。
这可能会在现有代码中引入错误,这些错误很难找到。
权衡收益和成本。
旨在提高可读性,缩短代码并减少括号。
请记住,使用过多的自定义Prolog运算符还会混淆代码并使读者感到困惑。
在不同域中使用标准运算符之前,请三思。
让我们以预定义的(\/)/2
为例。
它是算术表达式中可评估的函子,与(is)/2
,(=:=)/2
,(<)/2
等一起使用。
clpfd使用它来表示集合联合,例如1..3 \/ 5..7
-很好!
但是,使用它来表示列表串联是有问题的。
让我们解决您的实际问题!
请考虑使用(=..)/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)].