我有一个关于这个主题(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-如何编写“如果终端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的新手,所以所有技巧都是受欢迎的(是的,我知道我应该把同一个谓词的子句放在一起)。
发布于 2014-01-30 12:05:12
在第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发生冲突。
编辑基于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/1和signal/2谓词之间的关系,它们之间仍然存在无限递归的潜在危险。一些值得注意的东西。
基于OP的进一步注释的编辑现有的“未实例化变量”问题的根本原因是,也正在查询检查是否存在的terminal/1谓词以生成一个终端。但是,一致性检查的逻辑并不是为了生成一个新的终端,而是为了检查一个现有的终端(或者至少检查一个已经实例化的终端)。
如果偶然性检查子句的唯一目的只是为了检查它的重要性,那么它可能需要一个不同的名称并相应地被调用。
https://stackoverflow.com/questions/21432199
复制相似问题