Combining constraints with catch/3 - prolog

Answers to this question are eligible for a +300 reputation bounty. Bounty grace period has ended.
repeat is looking for an answer from a reputable source.
How do SICStus Prolog style attributed variables and the catch/throw Prolog exception handling mechanism interact?
Deep within the source code of library(clpz), there's a piece of code I don't quite comprehend:
with_local_attributes(Vars, Goal, Result) :-
catch((Goal,
maplist(del_all_attrs, Vars),
% reset all attributes, only the result matters
throw(local_attributes(Result,Vars))),
local_attributes(Result,Vars),
true).
The auxiliary code of del_all_attrs/1 is this:
del_all_attrs(Var) :-
( var(V)
-> put_atts(V, -clpz(_)),
put_atts(V, -clpz_aux(_)),
put_atts(V, -clpz_relation(_)),
% ... a lot more put_atts/2 goals follow ...
put_atts(V, -clpz_gcc_vs(_)),
put_atts(V, -clpz_gcc_num(_)),
put_atts(V, -clpz_gcc_occurred(_))
; true
).
Now, following the steps of these two predicates is not that hard,
but what effect does it all have for the involved variables and constraints?
The way I see it now the following happens:
Goal is executed; this may (and usually does) include the propagation of constraints.
All attributes are removed from variables in Vars; this effectively leaves all non-aliased variables as free variables, but preserves variable aliasing and ground values.
throw/3 creates a copy of Vars and then undoes the effects of steps (1) and (2).
catch/3 unifies the copy of Vars with the original Vars.
As a result all aliases and ground values that were present in Vars after the execution of Goal are "preserved", but all constraints are effectively reset. Execution resumes with waking some constraints by unifying Vars with the "returned" copy.
Am I on the right way?
And can I express this without catch/3, maybe by using copy_term/3?

Related

Prolog singleton variables in rule head causes program to output booleans for all queries

I have this prolog program.
red(rose).
red(anthurium).
white(rose).
white(gardenia).
white(jasmine).
like(Y,X) :-
red(X),!,
fail
;
white(X).
And below is how it responds to different queries.
?- like(rose,gardenia).
true.
?- like(rose,P).
false.
?- like(Val,anthurium).
false.
?- like(rose,X).
false
The problem I now have is this:
When querying with a variable within the query (Eg: ?- like(rose,X).), Prolog usually responds by returning a value, (something like X=some_val). Why I don't get any value for those variables, but either true or false?
All helpful answers are highly appreciated. Thanks in advance.
Think about what Prolog is doing here:
like(rose,P) succeeds if red(P), so it grabs a possible substitution for P, namely rose or anthurium. Then it traverses the cut and then it fails. But "failing" means that the proof search down that path didn't bring any solution, there are no successful bindings to report (the only fail to get information out of a failing branch is to side-effect to a log file and read check it later). In fact, all bindings will be undone on backtracking. The second branch is white(X), but rose is not white, so we fail here, too.
You can also write:
like(_,X) :- \+ red(X).
like(_,X) :- white(X).
which is a bit more readable. One notices that when calling like(_,X), the goal enclosed by the negation-as-failure operator \+ is nonground. This is bad, and causes a floundering query (in other words, don't do that). I have written this little page on "floundering".

System State in Prolog

I have a small program that runs in python. Basically, it has a pretty simple loop: Query a Prolog program, do something with the result, change some state back in Prolog.
I have written a logical way (no mutations) to change a state in Prolog.
The queries use a state as their argument, and result in a new state. The question is, where do I store the new state?
I can pass it back and forth from Prolog to Python, but as the state grows large it might become problematic.
I can also store a global variable, but that seems like a bad solution.
This is the basic flow of my program:
some_query(OldState, NewState) :-
% do some stuff here
python code:
state = '[]'
while Not_Exit:
query = MyLogic(state) # state is not actually used here (python-wise), just to pass it to prolog
result = prologBridge.Query(query)
state = result["NewState"] # how do I change that in Prolog without passing the state back and forth?
EDIT:
The state contains a list of terms, and state changes revolve around adding and removing terms. For example. S1 = [T1, T2, T3] changes into S2 = [T2, T3, T4].
Possible solutions:
Store state or other facts in a file that you reconsult in Prolog.
Use data bases to persist state
Keep Prolog running as a separate process in the background, then current state should be available.
What is your choice ? what about functional programming ?
As long as each query runs in the same Prolog session (i.e., you don't start a new Prolog each time), you can use Prolog's built-in database. This is a store of "dynamic" Prolog clauses that can be modified at runtime.
You declare a dynamic predicate using a :- dynamic directive. You remove old facts using rectract or retractall and assert new ones using asserta or assertz. Querying a dynamic predicate is done by calling it as usual.
For example, you can declare your state like this:
:- dynamic mystate/1.
A predicate querying the state, computing the next one, and updating the database, looks like this:
query_and_update_state :-
mystate(OldState),
some_query(OldState, NewState),
write('new state: '),
write(NewState),
nl,
retractall(mystate(_)),
asserta(mystate(NewState)).
This assumes the existence of your some_query predicate. Some initial state must be set at the beginning as well. For example, if the state is just a counter:
init_state :-
retractall(mystate(_)),
asserta(mystate(0)).
some_query(Old, New) :-
succ(Old, New).
Running this interactively:
?- init_state.
true.
?- query_and_update_state.
new state: 1
true.
?- query_and_update_state.
new state: 2
true.
?- query_and_update_state.
new state: 3
true.
?- query_and_update_state.
new state: 4
true.
Your Python code would call init_state once and then call query_and_update_state repeatedly, presumably for some side effect. (It's not clear to me from your question.)
Caveat: If you're worried about the costs of copying the state, you might not be happy about this either. Asserting a state and querying it both involve making a complete deep copy of the data structure. Such a Prolog-Prolog copy might indeed be cheaper than a Prolog-Python copy. But depending on your Python-Prolog bridge, maybe it doesn't make a deep copy and could be cheaper? I don't know.

Grounding head and body

I'm writing a software using SWI-Prolog where i have to find all the groundings of a predicate. In particular all the subtitutions that grounds the head and relative body supposing i can access independently head and body. Here an example of the behaviour i would like to obtain:
student(a).
student(b).
student(c).
play.
study(A):-
play,
student(A).
ground(Head,Body,Result):-
% some code
...
?- ground([study(A)],[play, student(A)],R).
R = [
[study(a):- play, student(a)],
[study(b):- play, student(b)],
[study(c):- play, student(c)]
]
And maybe generalize to:
dog(d).
dog(e).
study(A,B):-
play,
dog(B),
student(A).
?- ground([study(A,B)],[play, dog(B),student(A)],R).
R = [[study(a):- play, dog(d), student(a)] ... ]
So, for the body, find all non ground variables, ground them and then ground the head variables. Basically find all the combinations. The problem is to manage the body...
Maybe i can use for instance =../2, functor/3 and call/1 but i don't know how to takle the body (see this question/answer).
Thanks!
I am not sure why in the examples you provide the goal is inside a list and you also provide the body.
The procedure in this answer takes a goal, gets a matching clause and then gets all the solutions (binding the variables on the way). It may leave some variable unbound if they are not grounded by the goal. Upon backtracking it may take other clauses that match the initial goal.
ground(Goal, Body, LGroundClauses):-
clause(Goal, Body),
findall((Goal:-Body), call(Body), LGroundClauses).
sample run:
?- ground(study(A), Body, LClauses).
Body = (play, student(A)),
LClauses = [
(study(a):-play, student(a)),
(study(b):-play, student(b)),
(study(c):-play, student(c))
]
Note on the question and accepted solution that's a bit too long for a comment.
#gusbro writes (emphasis mine): "I am not sure why in the examples you provide the goal is inside a list and you also provide the body." I would also like to see a clarification on this point.
The ISO Prolog Core standard allows the clause/2 predicate to retrieve clauses for public predicates. But most Prolog systems, with a notably exception being SWI-Prolog, only allow using clause/2 to access clauses of dynamic predicates. Moreover, SWI-Prolog protect_static_code flag can be set to true to disable using clause/2 on static predicates. This makes the solution non-portable (and possibly undesirable in a deployment scenario) unless the predicates are declared dynamic. A possible alternative, assuming that indeed the Body argument is bound in a ground(Head,Body,Result) goal, would be to construct the clause body using the list of goals. Something like:
ground(Goal, BodyGoals, LGroundClauses):-
list_to_conjunction(BodyGoals, Body),
findall(Goal:-Body, call(Body), LGroundClauses).
This would remove the requirement of calling clause/2 and possibly making the predicates dynamic for portability. But does it make sense in your case?

Prolog: Rules with nothing but anonymous variables in the head, and no body

Prolog's grammar uses a <head> :- <body> format for rules as such:
tree(G) :- acyclic(G) , connected(G).
, denoting status of G as a tree depends on status as acyclic and connected.
This grammar can be extended in an implicit fashion to facts. Following the same example:
connected(graphA) suggests connected(graphA):-true.
In this sense, one might loosely define Prolog facts as Prolog rules that are always true.
My question: Is in any context a bodiless rule (one that is presumed to be true under all conditions) ever appropriate? Syntactically such a rule would look as follows.
graph(X). (suggesting graph(X):-true.)
Before answering, to rephrase your question:
In Prolog, would you ever write a rule with nothing but anonymous variables in the head, and no body?
The terminology is kind of important here. Facts are simply rules that have only a head and no body (which is why your question is a bit confusing). Anonymous variables are variables that you explicitly tell the compiler to ignore in the context of a predicate clause (a predicate clause is the syntactical scope of a variable). If you did try to give this predicate clause to the Prolog compiler:
foo(Bar).
you will get a "singleton variable" warning. Instead, you can write
foo(_).
and this tells the compiler that this argument is ignored on purpose, and no variable binding should be attempted with it.
Operationally, what happens when Prolog tries to prove a rule?
First, unification of all arguments in the head of the rule, which might lead to new variable bindings;
Then, it tries to prove the body of the rule using all existing variable bindings.
As you can see, the second step makes this a recursively defined algorithm: proving the body of a rule means proving each rule in it.
To come to your question: what is the operational meaning of this:
foo(_).
There is a predicate foo/1, and it is true for any argument, because there are no variable bindings to be done in the head, and always, because no subgoals need to be proven.
I have seen at least one use of such a rule: look at the very bottom of this section of the SWI-Prolog manual. The small code example goes like this:
term_expansion(my_class(_), Clauses) :-
findall(my_class(C),
string_code(_, "~!##$", C),
Clauses).
my_class(_).
You should read the linked documentation to see the motivation for doing this. The purpose of the code itself is to add at compile time a table of facts to the Prolog database. This is done by term expansion, a mechanism for code transformations, usually used through term_expansion/2. You need the definition of my_class/1 so that term_expansion/2 can pick it up, transform it, and replace it with the expanded code. I strongly suggest you take the snipped above, put it in a file, consult it and use listing/1 to see what is the effect. I get:
?- listing(my_class).
my_class(126).
my_class(33).
my_class(64).
my_class(35).
my_class(36).
true.
NB: In this example, you could replace the two occurrences of my_class(_) with anything. You could have just as well written:
term_expansion(foobar, Clauses) :-
findall(my_class(C),
string_code(_, "~!##$", C),
Clauses).
foobar.
The end result is identical, because the operational meaning is identical. However, using my_class(_) is self-documenting, and makes the intention of the code more obvious, at least to an experienced Prolog developer as the author of SWI-Prolog ;).
A fact is just a bodiless rule, as you call it. And yes, there are plenty of use cases for bodiless facts:
representing static data
base cases for recursion
instead of some curly brace language pseudo code
boolean is_three(integer x) {
if (x == 3) { return true; }
else { return false; }
}
we can simply write
is_three(3).
This is often how the base case of a recursive definition is expressed.
To highlight what I was initially looking for, I'll include the following short answer for those who might find themselves asking my initial question in the future.
An example of a bodiless rule is, as #Anniepoo suggested, a base case for a recursive definition. Look to the example of a predicate, member(X,L) for illustration:
member(X,[X|T]). /* recursive base case*/
member(X,[H|T]):- member(X,T).
Here, the first entry of the member rule represents a terminating base case-- the item of interest X matching to the head of the remaining list.
I suggest visiting #Boris's answer (accepted) for a more complete treatment.

Defining a rule that the user cannot query

How do I define a rule that the user cannot query?
I only want the program itself to call this rule through another rule.
Ex:
rule1():- rule2().
rule2():- 1<5.
?-rule1().
true
?-rule2().
(I don't know what the answer will be, I just want this query to fail!)
Use a Logtalk object to encapsulate your predicates. Only the predicates that you declare public can be called (from outside the object). Prolog modules don't prevent calling any predicate as using explcit qualification bypasses the list of explicitly exported predicates.
A simple example:
:- object(rules).
:- public(rule1/1).
rule1(X) :-
rule2(X).
rule2(X) :-
X < 5.
:- end_object.
After compiling and loading the object above:
?- rules::rule1(3).
true.
?- rules::rule2(3).
error(existence_error(predicate_declaration,rule2(3)),rules::rule2(3),user)
If you edit the object code and explicitly declare rule2/1 as private you would get instead the error:
?- rules::rule2(3).
error(permission_error(access,private_predicate,rule2(3)),rules::rule2(3),user)
More information and plenty of examples at http://logtalk.org/
First, some notes:
I think you mean "predicate" instead of "rule". A predicate is a name/k thing such as help/0 (and help/1 is another) and can have multiple clauses, among them facts and rules, e.g. length([], 0). (a fact) and length([H|T], L) :- ... . (a rule) are two clauses of one predicate length/2.
Do not use empty parenthesis for predicates with no arguments – in SWI-Prolog at least, this will not work at all. Just use predicate2 instead of predicate2() in all places.
If you try to call an undefined predicate, SWI-Prolog will say ERROR: toplevel: Undefined procedure: predicate2/0 (DWIM could not correct goal) and Sicstus-Prolog will say {EXISTENCE ERROR: predicate2: procedure user:predicate2/0 does not exist}
Now, to the answer. Two ideas come to my mind.
(1) This is a hack, but you could assert the predicate(s) every time you need them and retract them immediately afterwards:
predicate1 :-
assert(predicate2), predicate2, retractall(predicate2).
If you want a body and arguments for predicate2, do assert(predicate2(argument1, argument2) :- (clause1, clause2, clause3)).
(2) Another way to achieve this would be to introduce an extra argument for the predicate which you do not want to be called by the user and use it for an identification that the user cannot possibly provide, but which you can provide from your calling predicate. This might be a large constant number which looks random, or even a sentence. This even enables you to output a custom error message in case the wrong identification was provided.
Example:
predicate1 :-
predicate2("Identification: 2349860293587").
predicate2(Identification) :-
Identification = "Identification: 2349860293587",
1 < 5.
predicate2(Identification) :- Identification \= "Identification: 2349860293587",
write("Error: this procedure cannot be called by the user. Use predicate1/0 instead."),
fail.
I don't use the equivalent predicate2("Identification: 2349860293587") for the first clause of predicate2/0, because I'm not sure where the head of the clause might appear in Prolog messages and you don't want that. I use a fail in the end of the second clause just so that Prolog prints false instead of true after the error message. And finally, I have no idea how to prevent the user from looking up the source code with listing(predicate2) so that will still make it possible to simply look up the correct identification code if s/he really wants to. If it's just to keep the user from doing accidental harm, it should however suffice as a protection.
This reminds me to facility found in Java. There one can query the
curent call stack, and use this to regulate permissions of calling
a method. Translated to Prolog we find in the old DEC-10 Prolog the
following predicate:
ancestors(L)
Unifies L with a list of ancestor goals for the current clause.
The list starts with the parent goal and ends with the most recent
ancestor coming from a call in a compiled clause. The list is printed
using print and each entry is preceded by the invocation number in
parentheses followed by the depth number (as would be given in a
trace message). If the invocation does not have a number (this will
occur if Debug Mode was not switched on until further into the execution)
then this is marked by "-". Not available for compiled code.
Since the top level is usually a compiled predicate prolog/0, this could be
used to write a predicate that inspects its own call stack, and then decides
whether it wants to go into service or not.
rule2 :- ancestors(L), length(L,N), N<2, !, write('Don't call me'), fail.
rule2 :- 1<5.
In modern Prologs we don't find so often the ancestors/1 predicate anymore.
But it can be simulated along the following lines. Just throw an error, and
in case that the error is adorned with a stack trace, you get all you need:
ancestors(L) :- catch(sys_throw_error(ignore),error(ignore,L),true).
But beware stack eliminiation optimization might reduce the stack and thus
the list returned by ancestors/1.
Best Regards
P.S.: Stack elimination optimization is already explained here:
[4] Warren, D.H.D. (1983): An Abstract Prolog Instruction Set, Technical Note 309, SRI International, October, 1983
A discussion for Jekejeke Prolog is found here:
http://www.jekejeke.ch/idatab/doclet/prod/en/docs/10_pro08/13_press/03_bench/05_optimizations/03_stack.html

Resources