Reputation: 135
I'm trying to use Prolog to reason about constraints and then query the knowledgebase to pass these constraints on to a solver (can't use clpfd).
%a first example would be constrainsquare(Row,Col,Val)
constrainsquare(1,1,3).
constrainsquare(1,2,2).
and I can then query all constraints using something like bagof/3
. This is not statisfactory because I also want to be able to write
constrainsquare(3,4,8):-constrainsquare(3,3,7).
The ability to say that if the solution has a 7
at position 3,3
; it necessarily has an 8
at position 3,4
.
Now you can no longer gather all constraints using something like bagof/3
.
How would you do this ideomatically in prolog?
Note that I cannot simply do
constrainsquare(L) :-
member(cs(1,1,3),L),
member(cs(1,2,2),L),
member(cs(3,4,8),L),
member(cs(3,3,7),L).
because I'm receiving new facts about the solution periodically and cannot alter existing facts.
At the moment I'm thinking about using a list of constraints and doing something like
info(cell(1,1,3)).
info(cell(1,2,2)).
constrainsquare(I,[I]).
partialinfo(cell(3,4,8),cell(3,3,7)).
....
and then query it by running bagoff to obtain [cell(1,1,3)],[cell(1,2,2)]...
and then folding/appending to [cell(1,1,3),cell(1,2,2)]
but this feels a bit 'meh'. I want to know the "proper" way.
Upvotes: 0
Views: 127
Reputation: 58324
Let's suppose you had query, we'll call it Q
, that you wished to run on a set of hypothetical facts. We'll call the set of facts, Facts
. You could write a predicate which would run the query on those facts dynamically as follows:
what_if_query(Q, Facts) :-
maplist(assertz, Facts),
call(Q),
maplist(retract, Facts).
If Q
takes one argument for results, R
, then we could write:
what_if_query(Q, Facts, R) :-
maplist(assertz, Facts),
call(Q, R),
maplist(retract, Facts).
Then, if you had a list of scenarios of facts, you could write:
what_if_scenarios(Scenarios, Q, Results) :-
maplist(what_if_query(Q), Scenarios, Results).
A "fact" can be any assertable Prolog term, and so could also be a rule: (Head :- P1, P2, ..., Pn)
. For example, your list of "facts" could be:
[cs(1,1,3), cs(1,2,2), (cs(3,4,8) :- cs(3,3,7))]
Upvotes: 1