Prolog: Getting predicate solutions and asserting

2019-07-03 04:47发布

I've got a specific problem but I'll just try and come up with a general question so other people might benefit from it too...

I've got a predicate that returns many solutions i.e.

X=5; X=2; X=7

and I want a predicate that gets each of these solutions and asserts them as Prolog facts then so I end up with three facts in this case e.g.

fact(5) fact(2) fact(7)

so calling fact(5) would be true but calling fact(8) would be false because we never asserted it because it wasn't a solution.

But I don't want to have a predicate where you have to keep asking for solutions to assert each single fact. I want to call a predicate and have it go through all the solutions in the background, assert them and that's it.

One way of solving it is using findall to put all the solutions into a list and then just go through the list asserting each element of the list. However, I don't think this is very elegant. There must be a nicer way of doing it without fiddling around with lists.

标签: prolog
2条回答
男人必须洒脱
2楼-- · 2019-07-03 05:09

Use a failure-driven loop to force backtracking over all solutions:

?- computation(X), false.

You can ignore this query's declaratively false truth value with ignore/1:

?- ignore((computation(X),false)).
查看更多
贼婆χ
3楼-- · 2019-07-03 05:25

This functionality can be made using setof and making a second order predicate.

:- dynamic fact/1.

isAns(5).
isAns(2).
isAns(7).

computation(F) :- setof(X,call(F,X),S),factify(S).

factify([X|Xs]) :- assert(fact(X)),factify(Xs).
factify([]).

Then when we go and ask about facts we get:

computation(isAns), fact(X).
X = 5;
X = 2;
X = 7;
false 
查看更多
登录 后发表回答