写作Prolog规则的指导

时间:2013-03-11 19:17:24

标签: prolog rule

我正处于Prolog编写代码的初始阶段,我仍在尝试围绕这个范例,所以请原谅这个问题的原始性。

我在维基百科上读到

A rule is of the form
Head :- Body.
and is read as "Head is true if Body is true".

这很简单。所以我正在构建一个模拟1位加法器功能的知识库。

这样做,我正在尝试为以下内容创建规则:

  

如果存在门X,X是AND门,则X.   有一个终端走出它,那个终端有一个信号和   信号为0然后,门X也必须至少有一个输入端   信号为0。

作为Prolog规则,我写这篇文章是为了反映我的上述句子:

gate(X) /\ gate_type(X, and) /\ terminal(T, X, out) /\ signal(T, SIG) /\ (SIG is 0) :- (gate(X) /\ gate_type(X, and) /\ terminal_type(R, X, in) /\ signal(R, 0)).

为了测试我的规则,我有一个终端t7,它是AND门的终端。

terminal_type(t7, a1, in).
gate_type(a1, and).

当我问Prolog:signal(t7, 1), signal(t8, 1), signal(t9, X).或类似的事情时,Prolog先生告诉我

X = 1;
X = 0;

我得到的答案应该只是X = 1.

1 个答案:

答案 0 :(得分:2)

欢迎来到Prolog编程!从硬件上来看它非常酷,几乎与你可以得到的一样远。

我想我看到了两个问题。

第一个是你的定义省略了AND门的定义特征,即当两个输入都是1时,输出将是1.你对Prolog的翻译有点奇怪,但当然应该把它带入帐户。所以我想在Prolog你想说的是:

signal(R, 0) :- 
  gate(X), gate_type(X, and), 
  terminal_type(R, X, out),
  terminal_type(R1, X, in), signal(R1, 0).

但这不是全部故事。你也需要这个:

signal(R, 1) :- 
  gate(X), gate_type(X, and), 
  terminal_type(R, X, out),
  terminal_type(R1, X, in), terminal_type(R2, X, in), R1 \= R2,
  signal(R1, 1), signal(R2, 1).

这可能是正确的,但第二个问题是signal(t7, 1)不是断言,因此它不会在您的事实数据库中结束。它只是一个光头结构,因此它不会为您的查询添加任何内容。最简单的解决方案是直接将其添加到您的数据库中:

signal(t7, 1).
signal(t8, 1).

然后进行查询:

signal(t9, X).

或者,你可以assertz/1

assertz(signal(t7, 1)), assertz(signal(t8, 1)), signal(t9, X).

但这有点草率,因为assert是一种副作用,在回溯时没有被撤消。

在实践中,大多数情况下,您可以通过传递它来创建动态查询的一部分,或者将其作为事实数据库的一部分。混合这两者很难理解。

如果我是你,我可能会通过将不同事实“类型”的数量减少到更像这样的东西来简化事情:

% gate(Name, Type, Input1, Input2, Output)
gate(a1, and, t7, t8, t9).

然后你可以真正简化谓词:

signal(Out, 0) :-
  gate(_, and, R1, R2, Out),
  ( signal(R1, 0) ; signal(R2, 0)).
signal(Out, 1) :-
  gate(_, and, R1, R2, Out),
  signal(R1, 1),
  signal(R2, 1).