How to generate a rule to tell that this simple fa

2019-07-11 20:02发布

问题:

So I have a couple of facts:

%bridge(Name,From,To).
bridge(a,1,2).
bridge(b,1,2).
bridge(c,2,3).
bridge(d,3,4).

Edit:changed to atoms

So this reads like "bridge A crosses from zone 1 to zone 2". This is simple. However, the inverse is also true. Bridge A crosses from zone 2 to zone 1. That's why I thought:

bridge(B,S,E):- bridge(B,E,S).

Thing is, this messes up my program because whenever swi-prolog can't find a match for a bridge, it will keep using the bridge rule to invert it's parameters over and over again. Is there any way to stop this? Or is there any other way to create a simple rule? My program works flawlessly if I add every other fact (bridge(A,2,1), bridge(C,3,2), etc).

回答1:

First note that you seem to be using variables where you meant to use atoms to identify bridges.

As to your question: You can easily solve this by adding the additional required facts, for example:

bridge(a, 1, 2).
bridge(a, 2, 1).

bridge(b, 1, 2).
bridge(b, 2, 1).

etc.

However, as you already seem to have noticed intuitively, this is clearly redundant and you can refactor it with an auxiliary predicate, say for example bridge_/2, that consists of two clauses:

bridge(B, X, Y) :- bridge_(B, X, Y).
brigde(B, X, Y) :- bridge_(B, Y, X).

bridge_(a, 1, 2).
bridge_(b, 2, 1).
bridge_(c, 2, 3).
etc.


回答2:

Prolog offers a way to process each clause read, before asserting it, by means of term_expansion/2. Should work this way:

term_expansion(bridge(K,A,B), bridge(K,A,B)) :- assertz(bridge(K,B,A)).

That is, it 'returns' the unchanged term read, and add a term with swapped 'connections'. Beware that could be difficult to get debug your transformed source with the graphical tracer...

edit my answer was a bit superficial, I'm trying to debug it...

edit thanks to Paulo hint, here is something working...

:- module(bridge, [bridge/3]).

term_expansion(bridge(K,A,B), [bridge(K,A,B),bridge(K,B,A)]).

bridge(a,1,2).
bridge(b,1,2).
bridge(c,2,3).
bridge(d,3,4).


标签: prolog