使Prolog语法看起来像一阶逻辑语法的方法?

问题描述 投票:0回答:3

我正在寻找方法使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 for ==>按预期工作。不知道为什么会这样......

syntax prolog
3个回答
1
投票

此答案涉及您更新的问题(“更新20190313”)。

定义运算符时要小心:

  1. 不要重新定义标准运算符,更改其说明符/优先级。 这可能会在现有代码中引入很难找到的错误。
  2. 预先计算好处和成本。 瞄准可读性,更短的代码和更少的括号。 请记住,使用太多自定义Prolog操作符也会混淆代码并使读者感到困惑。
  3. 在不同域中使用标准运算符之前请三思。 我们以预定义的(\/)/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)].

5
投票

在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

4
投票

以下是一些可以帮助您的Unicode字符:

¬ 

→ ⇒

← ⇐

∨ ∧

∀ ∃

我使用op/3将合适的优先级定义为挑战。

一旦有了这些定义,就可以用它们编写一阶句子。然后,您可以将这些句子转换为Prolog,或者使用Prolog解释它们。

© www.soinside.com 2019 - 2024. All rights reserved.