在Prolog中,断言和收回会导致查询失败的原因有哪些?

在Prolog中,断言和收回会导致查询失败的原因有哪些?,prolog,prolog-assert,Prolog,Prolog Assert,我正在将Logic De Morgan规则应用于集合的所有节点。每当我断言/收回与指定格式匹配的节点时,查询似乎会停止并返回no。虽然这不会导致应用De Morgan规则一次出现问题,但当我尝试多次应用它时,会导致问题,因为它会立即导致查询失败。我已经做了相当多的测试,所以我相当确定问题出在哪里,但请随意推荐一些我可能错过的东西---------- De Morgan规则:-(A V B)->A和-B_uuuuuuuuuu显示为not(或(A,B)->和(not(A),not(B))。新节点名称

我正在将Logic De Morgan规则应用于集合的所有节点。每当我断言/收回与指定格式匹配的节点时,查询似乎会停止并返回no。虽然这不会导致应用De Morgan规则一次出现问题,但当我尝试多次应用它时,会导致问题,因为它会立即导致查询失败。我已经做了相当多的测试,所以我相当确定问题出在哪里,但请随意推荐一些我可能错过的东西---------- De Morgan规则:-(A V B)->A和-B_uuuuuuuuuu显示为not(或(A,B)->和(not(A),not(B))。新节点名称只为调整后的节点生成新标记

%These are the preset nodes
:- dynamic(node/4).
node(n1, 'and', n3, n2).
node(n2, 'not', n6, void).
node(n3, 'not', n4, void).
node(n4, 'or', n5, n9).
node(n5, 't', void, void).
node(n9, 'u', void, void).
%node(n3, 'or', n4, n5).
%node(n4, 'r', void, void).
%node(n5, 'or', n9, n10).
node(n6, 'or', n7, n8).
node(n7, 'p', void, void).
node(n8, 's', void, void).

printTree(X) :- 
    node(X, Value, Left, Right),
    format('~w', [Value]),
    ( Value = 'and' -> write('(') ; true),
    ( Value = 'or' -> write('(') ; true),
    ( Value = 'not' -> write('(') ; true),
    printTree(Left),
    ( Value = 'and' -> write(',') ; true),
    ( Value = 'or' -> write(',') ; true),
    printTree(Right),
    ( Value = 'and' -> write(')') ; true),
    ( Value = 'not' -> write(')') ; true),
    ( Value = 'or' -> write(')') ; true).
printTree(void).

deMorgan(X) :- 
    
    node(X, 'not', Y, void),
    node(Y, Value, Left, Right),
    node(Left, Value1, void, void),
    node(Right, Value2, void, void),

    new_node_name(B, 2),
    new_node_name(C, 3), %simply generating tags for the asserted nodes
    new_node_name(D, 4),
    new_node_name(E, 5),

    asserta(node(X, 'and', B, C)),
    asserta(node(B, 'not', D, void)),
    asserta(node(C, 'not', E, void)),
    asserta(node(D, Value1, void, void)),
    asserta(node(E, Value2, void, void)),

    retract(node(X, 'not', Y, void)),
    retract(node(Y, Value, Left, Right)),
    retract(node(Left, Value1, void, void)),
    retract(node(Right, Value2, void, void)).
% seems to return 'no' after I retract, no matter where I place it.

new_node_name(X, Y):- 
    count_nodes(n1, N),
    Ne is N + Y,
    number_atom(Ne,NewAtom),
    atom_concat(n, NewAtom, X).

    
count_nodes(X,N):-
    node(X, Value, L, R),
    count_nodes(L,NL),
    count_nodes(R,NR),
    N is NL + NR + 1.
count_nodes(void,0).

相应的分支应该进行调整,但查询将返回no,尽管如此在
retract(节点(X,'not',Y,s))中的小写
s
看起来可疑。应该是变量
S
还是
void
,如果没有匹配的词可以收回,上面使用的方法将失败。
retract
。很抱歉,在创建帖子的过程中,这一定是滑到了那里。我检查了两次,原来的代码没有“S”。很遗憾,它被删除了dn无法解决此问题感谢您更新此内容。您是否也可以添加此问题?我想象使用
n2
n3
。此外,请添加
new_node_name
的实现,否则我们将无法测试程序。新的_node_名称可以用内置的gensym/2替换,例如
gensym(dn,B)
我认为它的预期用途是
deMorgan(X)
。每次你调用它时,它都会用应用deMorgan一次后获得的表达式更新知识库。这就足够按照你的意愿进行翻译了。我为
deMorgan(X)
X=n2;X=n3得到两个解决方案。
(~(t|u)&~(p|s))
变成
((~t&~u)和(~p&~s))
to run: 1. printTree(n1).
2. deMorgan(n2). or deMorgan(n3).
3. printTree(n1).
output: no 
expected output: yes