我有一个关于这个主题的问题(Create Prolog Vocabulary),但使用的词汇略有不同。
我已经看到了答案,即使我知道它是正确的,我也不想用这种方式描述电路。我希望能够确定终端和信号。
使用的词汇表之间的主要区别在于我的使用
signal(in(inPortNumber, portName), signalValue)
考虑到这一点,我有几个问题:
解决
1 - 如何写"如果C是电路,那么它的优点是I,J(I = numInPorts,J = numOutPorts)。对于N(0 这就是我所拥有的,但它不起作用(无限循环): 修改
2 - 如何写"如果T1和T2端子已连接,T2已分配信号,T1也被分配信号值"? 这就是我所拥有的: 问题是,在询问时: 它会抛出错误,因为事情没有充分实例化。
我知道问题出在哪里,有什么问题,但我不知道如何解决。 期待答案/建议。我是Prolog的新手,所以欢迎所有提示(但是,我知道我应该将同一谓词的条款放在一起)。% 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.
% 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).
答案 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)
似乎是无限循环的来源,因为它在signal
和terminal
之间创建了一个循环推理在这两个条款中。可能的解决方案是将signal/2
子句重命名为same_signal/2
,以避免与事实名称signal/2
冲突。
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/1
和signal/2
之间仍存在无限递归的潜在危险。值得关注的东西。
terminal/1
谓词以生成终端。但是,arity检查的逻辑并不是为了生成一个新的终端,而是为了检查现有终端(或者至少检查一个已经实例化的终端)。
如果arity check子句的唯一目的就是检查arity,那么它可能需要一个不同的名称并进行相应的调用。