0

I am applying the Logic De Morgan rule to all nodes of a set. Whenever I assert/retract the nodes matching the specified format, the query seems to stop there and return no. While this doesn't cause problems for applying the De Morgan rule once, it cause problems when I try to apply it multiple times as it fails the query immediately after. I've done a decent amount of testing so I am fairly sure where the problem is stemming but feel free to recommended something I probably missed.---------- De Morgan Rule: -(A V B) -> -A & -B____ Displays as not(or(A,B) -> and(not(A),not(B)). new_node_name just produces new tags for the adjusted nodes.

%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).
to run: 1. printTree(n1).
2. deMorgan(n2). or deMorgan(n3).
3. printTree(n1).
output: no 
expected output: yes 

Corresponding branch should adjust but the query will return no nonetheless

  • 2
    That lowercase `s` in `retract(node(X, 'not', Y, s))` looks suspicious. Should that be a variable `S` instead? Or `void`, the way you use it above? `retract` will fail if there is no matching term to retract. – Isabelle Newbie Oct 26 '20 at 21:37
  • sorry that must have slipped in there during the creation of the post. I doubled checked and the original code didn't have the 's'. So unfortunately it didn't fix the problem – thome.steve Oct 27 '20 at 16:37
  • Thanks for updating this. Could you also add to the question how you are calling this? I imagine with `n2` or `n3`. Also, add an implementation of `new_node_name` please, otherwise we won't be able to test the program. – Isabelle Newbie Oct 27 '20 at 17:15
  • new_node_name could be replaced with the inbuilt gensym/2 e.g `gensym(dn_, B)` And I think the intended use is `deMorgan(X)`. Each time you call it, it updates the knowledgebase with the expression obtained after applying deMorgan once. – 2bigpigs Oct 28 '20 at 11:30
  • That is enough to translate as you intend. I get two solutions for `deMorgan(X)` X = n2; X=n3. `(~(t | u) & ~(p | s))` becomes `((~t & ~u) & (~p & ~s))` – 2bigpigs Oct 28 '20 at 12:35
  • As Isabelle above said: can we get a version that runs -- [mcve]? Then we may get somewhere with it. – Topological Sort Oct 28 '20 at 13:17
  • Hi everyone, I have adjusted to a minimal reproducible example. Please let me know if there are any issues. thanks for the help – thome.steve Oct 28 '20 at 16:44
  • @thome.steve This works for me as is in GNU Prolog 1.4.5 on one machine. It throws a bizarre exception (not a `no` answer) in GNU Prolog 1.4.5 on another machine. It works in SWI-Prolog 7.6.4 if I change `number_atom` to `atom_number` (with flipped arguments). Could you tell us more about what Prolog system you are using (including version and operating system)? – Isabelle Newbie Oct 29 '20 at 17:17

0 Answers0