0

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

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

使用的词汇之间的主要区别是我使用

signal(in(inPortNumber, portName), signalValue)

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

已解决 1 - 我如何写“如果 C 是一个电路,让它的数量为 I, J (I = numInPorts, J = numOutPorts)。对于 N (0 < N < I) 的所有可能值,输入端口号 N C 是一个终端”?

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

% 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 - 如何编写“如果端子 T1 和 T2 已连接,并且已为 T2 分配了一个信号,则还为 T1 分配了该信号值”?

这就是我所拥有的:

% 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 的新手,所以欢迎所有提示(但是是的,我知道我应该将同一个谓词的子句放在一起)。

4

1 回答 1

2

在情况 1 中,如果 C 是一个电路,则让它的元数为 I, J (I = numInPorts, J = numOutPorts)。对于 N (0 < N < I) 的所有可能值,C 的入端口号 N 是一个终端

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)似乎是无限循环的来源,因为它在这两个子句之间signal和其中创建了循环推理。terminal一个潜在的解决方案是将signal/2子句重命名为same_signal/2,以避免与事实名称冲突signal/2
[根据 OP 更新的问题说明进行编辑] 指示错误时,最好说明准确的错误消息,在这种情况下,是ERROR: =</2: Arguments are not sufficiently instantiated. 在 prolog 中,不等式谓词 like=</2要求不等式的两边都被完全实例化。

您进入这种情况的原因是terminal(T1)or terminal(T2)insame_signal/2最终会调用谓词signal/2

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

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

除此之外,由于它们的谓词之间的关系,仍然存在无限递归的潜在terminal/1危险signal/2。有什么要注意的。


[根据OP的进一步评论进行编辑]现有“未实例化变量”问题的根本原因是terminal/1检查arity的谓词也被查询以生成终端。然而,arity 检查的逻辑并不是为了生成一个新的终端,而是为了检查一个现有的终端(或者至少检查一个已经实例化了 arity 的终端)。

如果 arity 检查子句的唯一目的只是为了检查 arity,那么它可能需要一个不同的名称并相应地调用。

于 2014-01-30T12:05:12.830 回答