编写Prolog规则的指导

编写Prolog规则的指导,prolog,rule,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是与门,X 它有一个终端,终端有一个信号 信号为0,则门X还必须至少有一个输入端子 它

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

我在维基百科上读过

A rule is of the form
Head :- Body.
and is read as "Head is true if Body is true".
这很简单。因此,我正在建立一个知识库,模拟1位加法器的功能

在此过程中,我试图为以下内容创建一个规则:

如果存在门X,X是与门,X 它有一个终端,终端有一个信号 信号为0,则门X还必须至少有一个输入端子 它的信号是0

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

gate(X)/\gate\u type(X,and)/\terminal(T,X,out)/\SIG(T,SIG)/\(SIG为0):-(gate(X)/\gate\u type(X,and)/\terminal\u type(R,X,in)/\sign(R,0))。

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

terminal_type(t7, a1, in).
gate_type(a1, and).
当我问Prolog时:
信号(t7,1)、信号(t8,1)、信号(t9,X)。
或诸如此类,Prolog先生告诉我

X = 1;
X = 0;

我得到的答案应该只有X=1。

欢迎使用Prolog编程!这是非常酷的,你正在从硬件来它,几乎从这个你可以得到的

我想我看到了两个问题

第一个是,您的定义省略了与门的定义特性,即当两个输入都为1时,输出将为1。你翻译成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
it:

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).

我认为你可能需要把你的规则改写成一个Horn条款:这太棒了。你给了我一些思考的东西。我很快就会尝试这个,请放心,我会有更多的反馈:p。再次感谢!当然可以。:)如果您有不适合S.O.格式的问题,请随时给我发电子邮件(查看我的个人资料)。谢谢。快速提示:
/=
是有效的运算符吗?编译器显示“应为运算符”。那应该是
\==
?你指的是我展示的上一个版本吗?在这种情况下,通过在
门/5
中的位置定义信号,可以避免这种可能性。如果你引用的是顶部的代码,你可以得到多个零,但它们都是“正确的”——当你应该得到0时,你不会得到1,反之亦然。如果您认为这也是一个问题,您可以使谓词更显式,就像真实情况一样。但原则上,额外的答案没有错,它们只是浪费。如果你想以其他方式驱动它,你可能需要为输入信号的
信号添加参数<代码>信号/2
正在工作,只是没有显示出来。但是,您可能需要一个新的谓词,以便将门逻辑与线逻辑分开。