我正处于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.
答案 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).