1

I am having the following issue in a Prolog program. The mathematical formulation of the problem is as follows:

Let Entanglements = the set of structures of the form entanglement(Symbol, Index, PosX, PosY), where Symbol is a character, Index an integer, and PosX and PosY variables (bound or unbound). For all entanglement(Symbol, Index, PosX, PosY) in Entanglements, with one of the two variables PosX or PosY bound and the other unbound, bind the unbound variable to Symbol.

After that, let RemEntanglements = all entanglement(Symbol, Index, PosX, PosY) in Entanglements with at least one of PosX and PosY bound.

Question: Given the set Entanglements, what are the Remaining Entanglements (RemEntanglements)?

My code does not function as intended. Could you give a hint as to what I ought to change?

function(Entanglements, RemEntanglements) :- findall(entanglement(Symbol, Index, PosX, PosY), (member(entanglement(Symbol, Index, PosX, PosY), Entanglements), (var(PosX), nonvar(PosY), PosX = Symbol; var(PosY), nonvar(PosX), PosY = Symbol)), Changed), findall(entanglement(Symbol1, Index1, PosX1, PosY1), (member(entanglement(Symbol1, Index1, PosX1, PosY1),Entanglements), (var(PosX1); var(PosY1))), RemEntanglements). 

Test query:

test(RemEntanglements) :- function([entanglement('0',2,'X',P3), entanglement('X',3,P3,P1), entanglement('0',4,P6,P7)], RemEntanglements). 

This query should work as follows: 1) Bind P3 to '0', given that entanglement('0',2,'X',P3) has one bound variable and an unbound one

2) RemEntanglements = [entanglement('X',3,'0',P1), entanglement('0',4,P6,P7)], given that P3 was already bound to the '0' symbol, but the others are still unbound.

The answer I got:

[entanglement('0', 2, 'X', _G11664), entanglement('X', 3, _G11655, _G11656), entanglement('X', 3, _G11647, _G11648), entanglement('0', 4, _G11639, _G11640), entanglement('0', 4, _G11631, _G11632)] 

Thank you in advance!

6
  • 1
    Can you please explicitly state in your question what is the problem? Are you not seeing any warnings at compilation time? Commented May 16, 2013 at 11:38
  • Also, there is an ISO predicate nonvar/1 which you should definitely use instead of \+ var(X) Commented May 16, 2013 at 11:39
  • Given the set Entanglements, compute the set RemEntanglements, while binding the variables PosX or PosY along the way. Commented May 16, 2013 at 12:10
  • No, I am not seeing any warning at compilation time. Commented May 16, 2013 at 12:22
  • 1
    Indeed, you are right about the Changed being a singleton variable. This predicate was part of a bigger one I wrote, in which the Changed variable was being used in another predicate, so there was no warning. It appears that P3, P6 and P7 are also singleton variables. Commented May 16, 2013 at 13:04

2 Answers 2

1

I think you're using the wrong predicate: findall(Template,Goal,List) it's a list generator, and works - abstractly - instancing Template in Goal, then copies Template in List. Then any binding in Goal will be undone among executions.

Then I would write in this way

function(Entanglements, RemEntanglements) :- maplist(instance, Entanglements), include(one_bound, Entanglements, RemEntanglements). instance(entanglement(Symbol, _Index, PosX, PosY)) :- ( ( var(PosX), nonvar(PosY) ) -> PosX = Symbol ; ( var(PosY), nonvar(PosX) ) -> PosY = Symbol ; true ). one_bound(entanglement(_Symbol, _Index, PosX, PosY)) :- nonvar(PosX) ; nonvar(PosY). test(RemEntanglements) :- function([ entanglement('0',2,'X',P3), entanglement('X',3, P3,_), entanglement('0',4, _,_)], RemEntanglements). 

that yields

?- test(L). L = [entanglement('0', 2, 'X', '0'), entanglement('X', 3, '0', 'X')]. 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! I had no idea about the way findall works. Thanks again!
1

The way it is written now, you should at least get rid of singleton variables. They almost always point to an error in the logic of your predicate. For one, you are binding variables in the first findall (to Changed) and then using the original list in the second findall, which is clearly not your intention.

The singleton variables in your test however should be unbound, you can start their names with an underscore to silence the warning.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.