【问题标题】:Guidance with writing Prolog rule编写 Prolog 规则的指导
【发布时间】:2013-03-11 19:17:24
【问题描述】:

我正处于在 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 THEN gate 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,它是与门的终端。

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。

【问题讨论】:

标签: prolog rule


【解决方案1】:

欢迎来到 Prolog 编程!从硬件出发,几乎与此相距甚远,这非常酷。

我认为我发现了两个问题。

第一个是您的定义忽略了与门的定义特征,即当两个输入均为 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).

【讨论】:

  • 这很棒。你给了我一些值得思考的事情。我很快就会尝试这个,请放心,我会得到更多反馈:p。再次感谢!
  • 当然。 :) 如果您有不适合 S.O. 的问题,请随时给我发电子邮件(查看我的个人资料)。格式。
  • 欣赏它。快速说明:/= 是有效的运算符吗?编译器说“操作员预期”。应该是\==
  • 你指的是我展示的最后一个版本吗?在这种情况下,您可以通过gate/5 中的位置定义的信号来避免这种可能性。如果你指的是顶部的代码,你可能会得到多个零,但它们都是“正确的”——当你应该得到 0 时你不会得到 1,反之亦然。如果您认为这也是一个问题,您可以使谓词更明确,就像真实情况一样。但原则上,不正确的额外答案没有错,它们只是浪费。
  • 如果您想以其他方式驱动它,您可能需要为输入信号添加参数到signalsignal/2 正在做这项工作,只是没有透露。但是您可能需要一个新的谓词,以便您可以将门逻辑与线逻辑分开。
猜你喜欢
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多