Prolog电路数据库

时间:2014-01-29 13:14:12

标签: prolog circuit

我有一个关于这个主题的问题(Create Prolog Vocabulary),但使用的词汇略有不同。

我已经看到了答案,即使我知道它是正确的,我也不想用这种方式描述电路。我希望能够确定终端和信号。

使用的词汇表之间的主要区别在于我的使用

signal(in(inPortNumber, portName), signalValue)

考虑到这一点,我有几个问题:

解决 1 - 如何写"如果C是电路,那么它的优点是I,J(I = numInPorts,J = numOutPorts)。对于N(0

这就是我所拥有的,但它不起作用(无限循环):

% Check arity of IN wires
% If more in wires than gate can support, it's an error
terminal(in(N, C)) :- circuit(C), arity(C, I, _J), N < I, N > 0.

修改 2 - 如何写&#34;如果T1和T2端子已连接,T2已分配信号,T1也被分配信号值&#34;?

这就是我所拥有的:

% FACTS
circuit('c1').
arity('c1', 3, 2).
gate('x1').
type('x1', xorGate).
are_connected(in(1, 'c1'), in(1, 'x1')).
are_connected(in(2, 'c1'), in(2, 'x1')).
signal(in(1, 'c1'), 1).
signal(in(2, 'c1'), 1).
signal(in(3, 'c1'), 1).

% RULES
% All gates are circuits
circuit(G) :- gate(G).

% Check arity of IN wires
terminal(in(N, G)) :- circuit(G), arity(G, I, _J), N =< I, N > 0.
% Check arity of OUT wires
terminal(out(N, G)) :- circuit(G), arity(G, _I, J), N =< J, N > 0.

% Signals do only exist in terminals
terminal(T) :- signal(T, _V).

% Arity
arity(G, 1, 1) :- gate(G), type(G, notGate). % NOT gate
arity(G, 2, 1) :- gate(G), type(G, V), not(V = notGate). % Other gates

% Commutativity
connected(T1, T2) :- are_connected(T1, T2), !.
connected(T2, T1) :- are_connected(T1, T2), !.

% Connectivity
same_signal(T1, T2) :- terminal(T1), terminal(T2), not(T1 = T2), connected(T1, T2).
signal(T1, V) :- same_signal(T1, T2), signal(T2, V), !.
signal(T2, V) :- same_signal(T1, T2), signal(T1, V), !.

问题是,在询问时:

signal(in(1, x1), V).

它会抛出错误,因为事情没有充分实例化。 我知道问题出在哪里,有什么问题,但我不知道如何解决。

期待答案/建议。我是Prolog的新手,所以欢迎所有提示(但是,我知道我应该将同一谓词的条款放在一起)。

1 个答案:

答案 0 :(得分:1)

在情况1中,如果C是电路,那么它的优点是I,J(I = numInPorts,J = numOutPorts)。对于N的所有可能值(0

terminal(in(N, C)) :-   % in(N, C) is a terminal if...
    circuit(C),         % C is a circuit and...
    arity(C, I, _J),    % Arity of C is I, _ and...
    N < I, N > 0.       % 0 < N < I

这似乎与您的自然语言描述相符。你提到它会导致一个无限循环,但是这个代码中没有任何东西可以导致这样的循环。您需要显示circuit/1的定义以进一步打破这一点。

在情况2中,如果连接了端子T1和T2,并且已为T2分配了信号,则还为T1分配了信号值

terminal(T) :- signal(T, V).  % T is a terminal if it is assigned a signal

signal(T1, V) :-       % T1 is assigned signal V if...
    terminal(T1),      % T1 is a terminal and...
    terminal(T2),      % T2 is another terminal and...
    connected(T1, T2), % T1 and T2 are connected and...
    signal(T2, V).     % T2 is assigned signal V

此处的第二个条款已经表达了您的完整描述。

<小时/> [根据OP的评论进行编辑]第一个子句terminal(T) :- signal(T, V)似乎是无限循环的来源,因为它在signalterminal之间创建了一个循环推理在这两个条款中。可能的解决方案是将signal/2子句重命名为same_signal/2,以避免与事实名称signal/2冲突。
[根据OP更新的问题陈述编辑]指示错误时,最好说明准确的错误消息,在本例中为ERROR: =</2: Arguments are not sufficiently instantiated。在prolog中,像=</2这样的不等式谓词要求完全实例化不等式的两面。

您遇到这种情况的原因是terminal(T1)中的terminal(T2)same_signal/2最终会调用谓词signal/2

terminal(T) :- signal(T, _V).

对于某些迭代,完全实例化的事实满足signal/2,并通过这些工作进行搜索。但是它最终将回溯到谓词signal/2(你有两个谓词的子句)并产生一个未实例化的终端。这会导致terminal/1谓词子句失败,因为N未实例化。

除此之外,由于其谓词之间的关系,terminal/1signal/2之间仍存在无限递归的潜在危险。值得关注的东西。

<小时/> [ EDIT基于OP的进一步评论] 现有“未实例化变量”问题的根本原因是还检查了检查arity的terminal/1谓词以生成终端。但是,arity检查的逻辑并不是为了生成一个新的终端,而是为了检查现有终端(或者至少检查一个已经实例化的终端)。

如果arity check子句的唯一目的就是检查arity,那么它可能需要一个不同的名称并进行相应的调用。