如何使Prolog语法看起来像一阶逻辑语法?

时间:2018-08-30 20:20:09

标签: syntax prolog

我正在寻找使Prolog程序“看起来”更像一阶逻辑的方法。我想拥有的东西例如:

  • ->暗示
  • 前辈->
  • ^表示连词v,表示析取

还是已经有其他软件实现了此功能?

谢谢!

/ 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用于==>,但是可以正常工作。不知道为什么会这样...

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”)。

在定义运算符时要小心:

  1. 不要重新定义标准运算符,更改其指定符/优先级。

    这可能会在现有代码中引入错误,这些错误很难找到。

  2. 权衡收益和成本。

    旨在提高可读性,缩短代码并减少括号。

    请记住,使用过多的自定义Prolog运算符还会混淆代码并使读者感到困惑。

  3. 在不同域中使用标准运算符之前,请三思。

    让我们以预定义的(\/)/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)].