Prolog: Getting predicate solutions and asserting them as facts

狂风中的少年 提交于 2019-12-23 20:14:20

问题


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.


回答1:


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)).



回答2:


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 


来源:https://stackoverflow.com/questions/4296687/prolog-getting-predicate-solutions-and-asserting-them-as-facts

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!