Is there a way to combine tabling with clause? - prolog

In my program, I use a simple recursive clause/2 to track my proving.
prove(X):-
clause(X, B),
B == true.
prove((X1, X2)):-
prove(X1),
prove(X2).
prove(X):-
X \= true,
X \= (_, _),
clause(X, B),
write(X), write(' <= '), write(B), nl,
prove(B).
What's more, I'm trying to use tabling to solve the exchangeability/transitivity problems. (I'm talking about f(a)=b <=> f(b)=a, f(a)=b, f(b)=c => f(a)=c, etc).
I know using transistive closure or a decorated predicate can help to solve this. However, I'm working on a lot of rules. If I do the same stuff for each group of rules, it would be a huge workload for me, and indeed, contributes to a lot of bugs right now.
However, firstly clause is tracing back to start_tabling.
[1] ?- prove(segment_equal(c,d,a,b)).
segment_equal(c,d,a,b) <= start_tabling(user:segment_equal(c,d,a,b),segment_equal tabled(c,d,a,b))
Secondly, it will raise Errors.
ERROR: No permission to access private_procedure `'$tbl_variant_table'/3'
So I'm wondering if I can use tabling to save my codes and track the procedure at the same time? Or any other better practice?
PS: If background provides any help, I'm working on a geometry automated theorem prover, as we known, those basic rules appear in many theorems, like segment equal, angle equal, etc.

A possible solution is to use the predicate_property/2 predicate to exclude which predicates that should not be traced. For example, the following meta-interpreter will only trace calls to dynamic predicates:
prove(X) :-
clause(X, B),
B == true.
prove((X1, X2)) :-
prove(X1),
prove(X2).
prove(X) :-
clause(X, B),
( predicate_property(B, dynamic) ->
write(X), write(' <= '), write(B), nl
; true
),
prove(B).
Depending on the used Prolog system, there may be other reflection predicates that would allow you to filter what should be traced. E.g. only predicates defined in whitelisted files.

Related

Use a rule if a fact doesn't exist in prolog?

I'm new to prolog.
The idea of my project is to say "The room X is free if none is a guest of X, while X is taken if a family lives in X".
I use a predicate
guest(FamilySurname,RoomTaken)
So this mean that a family has taken that room.
taken(X) :- guest(_,X).
So if a family lives in room X, then X is taken.
My problem is how could i say that the room X is free? I should use a kind of NOT, like:
free(X) :- "NOT EXIST" guest(_,X).
How could i translate that "NOT EXIST" in prolog?
I have tried with ! but it doesn't work properly... maybe I'm placing it in the wrong way.
Sorry for my english.
Check the following code:
taken(X, Y) :- guest(Y,X).
free(X) :- \+ guest(_,X).
I made the a little change to taken, now it shows you who is on that room.
guest(albert, 123).
?- taken(123, R).
R = albert.
And the free() predicate it's pretty straightforward, I used the negation operator, you can check How to negate in Prolog
The code in the first answer does not seem to be a solution, i.e. the query ?- free(X) will not give an answer, where as the query ?- free(foo) will be successful. One needs to consider query floundering in Prolog into account, i.e. all variables
Consider the following code in which two alternatives for presenting the free predicate.
room(123).
room(124).
guest(albert, 123).
taken(Room) :- guest(_, Room).
free2(Room) :- room(Room),
\+ taken(Room).
free(Room) :- room(Room),
forall(guest(_, RoomTaken),
RoomTaken \= Room).

Make a predicate reversible

I'm new to prolog; I'm coming from a structured programming background, as will become obvious :)
I am building up a prolog query that involves reversing a number; eg. reverse_num(123,X) results in X = 321. I came up with the following definition, but it only works when I provide a number as the first parameter.
reverse_num(Num, Revnum) :-
number_chars(Num, Atoms),
reverse(Revatoms, Atoms),
number_chars(Reversed, Revatoms),
Reversed = Revnum.
the number_chars/2 predicate doesn't like an unsubstantiated variable if I do: reverse_num(X,123) (where I'm expecting X to be 321).
Am I trying too hard to make reverse_num do something it shouldn't (should it be understood to work only with a number as the first parameter and variable as the second)?
Or is there an easy / straight-forward way to handle a variable as the first parameter?
Relational naming
Before jumping into coding, let's take a step back. After all, the idea in Prolog is to define relations. Your name reverse_num/2 rather suggests some actions, num_reversed/2 might be a better name.
Determine the relation
Your definition is not that bad, let me rewrite it to1:
num_reversed(Num, Reversed) :-
number_chars(Num, Chars),
reverse(Chars, Revchars),
number_chars(Reversed, Revchars).
?- num_reversed(123,X).
X = 321.
?- num_reversed(1230,X).
X = 321.
?- num_reversed(12300,X).
X = 321.
Do you see the pattern? All numbers N*10^I have the same result!
Now, let's ask some more:
?- num_reversed(Num, 321).
error(instantiation_error,number_chars/2).
Hm, what did we expect? Actually, we wanted all 123*10^I to be printed. That's infinitely many solutions. So above query, if correctly answered, would require infinitely many solutions to be printed. If we print them directly, that will take all our universe's lifetime, and more!
It is for this reason, that Prolog produces an instantiation error instead. By this, Prolog essentially states:
This goal is too general that I can make a good answer. Maybe there are infinitely many solutions, maybe not. I know not. But at least I indicate this by issuing an error. To remove this error you need to instantiate the arguments a bit more.
So the answer Prolog produced was not that bad at all! In fact, it is much better to produce a clean error than to, say, fail incorrectly. In general, Prolog's errors are often a very useful hint to what semantic problems you might have. See all error classes how.
Coroutining
As have other answers suggested, coroutining, using when/2 might solve this problem. However, coroutining itself has many semantic problems. Not without reason, systems like XSB do not offer it, due to the many problems related to subsumption checking. An implementation that would be compatible to it would be unexpectedly inefficient.
But for the sake of the point, we could make our definition more versatile by querying it like
?- when(nonvar(Num), num_reversed(Num, Reversed)).
when(nonvar(Num), num_reversed(Num, Reversed)).
Now we get back as an answer exactly the query we entered. This is also known as floundering. So there is a way to represent infinitely may solutions in a compact manner! However, this comes at a rather high price: You no longer know whether a solution exists or not. Think of:
?- when(nonvar(Num), num_reversed(Num, -1)).
when(nonvar(Num), num_reversed(Num, -1)).
Others have suggested to wait also for nonvar(Reversed) which would only be correct if we would produce infinitely many answers - but, as we have seen - this just takes too much time.
Coroutining looked as a very promising road at the beginning of the 1980s. However, it has never really caught on as a general programming methodology. Most of the time you get much too much floundering which is just a pain and even more difficult to handle than, say instantiation errors.
However, a more promising offspring of this development are constraints. There, the mechanisms are much cleaner defined. For practical purposes, programmers will only use existing libraries, like CLPFD, CLPQ, or CHR. Implementing your own library is an extremely non-trivial project in its own right. In fact it might even be possible to provide an implementation of num_reversed/2 using library(clpfd) that is, restricting the relation to the integer case.
Mode dependent conditionals
Traditionally, many such problems are solved by testing for instantiations explicitly. It is good style to perform this exclusively with nonvar/1 and ground/1 like the condition in when/2- other type test predicates lead easily to errors as exemplified by another answer.
num_reversed(Num, Reversed) :-
( nonvar(Num)
-> original_num_reversed(Num, Reversed)
; original_num_reversed(Reversed, Base),
( Base =:= 0
-> Num is 0
; length(_, I),
Num is Base*10^I
)
).
Above code breaks very soon for floats using base 2 and somewhat later for base 10. In fact, with classical base 2 floats, the relation itself does not make much sense.
As for the definition of number_chars/2, ISO/IEC 13211-1:1995 has the following template and mode subclause:
8.16.7.2 Template and modes
number_chars(+number, ?character_list)
number_chars(-number, +character_list)
The first case is when the first argument is instantiated (thus nonvar). The second case, when the first argument is not instantiated. In that case, the second argument has to be instantiated.
Note, however, that due to very similar problems, number_chars/2 is not a relation. As example, Chs = ['0','0'], number_chars(0, Chs) succeeds, whereas number_chars(0, Chs), Chs = ['0','0'] fails.
Very fine print
1 This rewrite is necessary, because in many Prologs reverse/2 only terminates if the first argument is known. And in SWI this rewrite is necessary due to some idiosyncratic inefficiencies.
The number_chars/2 predicate has the signature:
number_chars(?Number, ?CharList)
But although not fully specified by the signature, at least Number or CharList have to be instantiated. That's where the error occurs from.
If you call:
reverse_num(Num,123)
You will call number_chars/2 with both uninstatiated at that time so the predicate will error.
A not very nice solution to the problem is to ask whether Num or RevNum are number/2s. You can do this by writing two versions. It will furthermore filter other calls like reverse_num(f(a),b), etc.:
reverse_num(Num,Revnum) :-
\+ number(Num),
\+ number(Revnum),
throw(error(instantiation_error, _)).
reverse_num(Num, Revnum) :-
ground(Num),
number(Num),
!,
number_chars(Num, Atoms),
reverse(Revatoms, Atoms),
number_chars(Revnum, Revatoms).
reverse_num(Num, Revnum) :-
ground(Revnum),
number(Revnum),
reverse_num(Revnum,Num).
Or you can in case you use two nongrounds (e.g. reverse_num(X,Y).) an instantiation error instead of false as #false says:
reverse_num(Num,Revnum) :-
\+ number(Num),
\+ number(Revnum),
!,
throw(error(instantiation_error, _)).
reverse_num(Num, Revnum) :-
number(Num),
!,
number_chars(Num, Atoms),
reverse(Revatoms, Atoms),
number_chars(Revnum, Revatoms).
reverse_num(Num, Revnum) :-
reverse_num(Revnum,Num).
The cut (!) is not behaviorally necessary, but will increase performance a bit. I'm not really a fan of this implementation, but Prolog cannot always fully make predicates reversible since (a) reversibility is an undecidable property because Prolog is Turing complete; and (b) one of the characteristics of Prolog is that the body atoms are evaluated left-to-right. otherwise it will take ages to evaluate some programs. There are logic engines that can do this in an arbitrary order and thus will succeed for this task.
If the predicate/2 is commutative, a solution that can be generalized is the following pattern:
predicate(X,Y) :-
predicate1(X,A),
predicate2(A,B),
% ...
predicaten(C,Y).
predicate(X,Y) :-
predicate(Y,X).
But you cannot simply add the last clause to the theory, because it can loop infinitely.
Nice to see someone is also worried about define flexible rules with no restrictions in the set of bound arguments.
If using a Prolog system that supports coroutining and the when/2 built-in predicate (e.g. SICStus Prolog, SWI-Prolog, or YAP), try as:
reverse_num(Num, Reversed) :-
when( ( ground(Num); ground(Atoms) ), number_chars(Num, Atoms) ),
when( ( ground(Reversed); ground(Revatoms) ), number_chars(Reversed, Revatoms) ),
reverse(Atoms , Revatoms).
that gives:
?- reverse_num( 123, X ).
X = 321.
?- reverse_num( X, 123 ).
X = 321 .
( thanks to persons who provided theses answers: Prolog: missing feature? )
This SWISH session shows my effort to answer.
Then I've come back here, where I found I was on #PasabaPorAqui' mood (+1), but I didn't get it right.
But, such an interesting topic: notice how regular is the join pattern.
reverse_num(X, Y) :-
when((nonvar(Xs);nonvar(Ys)), reverse(Xs, Ys)),
when((nonvar(X) ;nonvar(Xs)), atomic_chars(X, Xs)),
when((nonvar(Y) ;nonvar(Ys)), atomic_chars(Y, Ys)).
So, we can generalize in a simple way (after accounting for PasabaPorAqui correction, ground/1 it's the key):
% generalized... thanks Pasaba Por Aqui
:- meta_predicate when_2(0).
when_2(P) :-
strip_module(P,_,Q),
Q =.. [_,A0,A1],
when((ground(A0);ground(A1)), P).
reverse_num(X, Y) :-
maplist(when_2, [reverse(Xs, Ys), atomic_chars(X, Xs), atomic_chars(Y, Ys)]).
I think I understand why nonvar/1 was problematic: the list bound for reverse get 'fired' too early, when just the head get bound... too fast !
maplist/2 is not really necessary: by hand we can write
reverse_num(X, Y) :-
when_2(reverse(Xs, Ys)),
when_2(atomic_chars(X, Xs)),
when_2(atomic_chars(Y, Ys)).
this seems an ideal application of term rewriting... what do you think about -:- ? Implementing that we could write bidirectional code like
reverse_num(X, Y) -:-
reverse(Xs, Ys),
atomic_chars(X, Xs),
atomic_chars(Y, Ys).
edit SWISH maybe is not 'term_rewrite' friendly... so here is a lower level approach:
:- op(900, xfy, ++).
A ++ B ++ C :- when_2(A), B ++ C.
A ++ B :- when_2(A), when_2(B).
reverse_num(X, Y) :-
reverse(Xs, Ys) ++ atomic_chars(X, Xs) ++ atomic_chars(Y, Ys).
Setting aside the problem of trailing zeroes turning into leading zeroes, it doesn't seem like it should be much more complicated than something like this (made somewhat more complicated by dealing with negative numbers):
reverse_number(X,Y) :- number(X) , ! , rev(X,Y) .
reverse_number(X,Y) :- number(Y) , ! , rev(Y,X) .
rev(N,R) :-
N < 0 ,
! ,
A is abs(N) ,
rev(A,T) ,
R is - T
.
rev(N,R) :-
number_chars(N,Ns) ,
reverse(Ns,Rs) ,
number_chars(R,Rs)
.
Note that this does require at least one of the arguments to reverse_number/2 to be instantiated.

How to write/edit own coroutines in Prolog?

I would like to build my own coroutines in Prolog.
I'd like to add some extra functionalities.
Writing a vanilla interpreter for coroutines should be on the teaching list of every Prolog course. It is quite simple, here you see the normal vanilla interpreter, simplified:
% solve(+Term)
solve(true).
solve((A,B)) :- solve(A), solve(B).
solve(H) :- clause(H, B), solve(B).
Now for corouting, in the sense of suspending goals via freeze/2, just add an additional input output parameter pair with the delayed goals, for a specification of select/3 see (*):
% solve(+Term, +List, -List)
solve(G, L, R) :- select(freeze(V, F), L, H),
nonvar(V), !,
solve((F,G), H, R).
solve(freeze(V, G), L, [freeze(V,G)|L]) :- var(V), !.
solve(freeze(_, G), L, R) :- solve(G, L, R).
solve(true, L, L).
solve((A,B), L, R) :- solve(A, L, H), solve(B, H, R).
solve(H, L, R) :- clause(H, B), solve(B, L, R).
You can use the above vanilla interpreter to study different wake-up strategies. I am not sure whether it captures existing Prolog systems. But you could run examples such as:
?- freeze(X, member(X, [the(1), the(2)])), X = the(Y).
successfully, by posing the following question:
?- solve((freeze(X, member(X, [the(1), the(2)])), X = the(Y), true), [], L).
The ", true" is needed to check a last time for woken up goals. If L is returned empty then all frozen goals where woken up. Otherwise there are some pending frozen goals. Which is sometimes called floundering.
The above prototype also leads to a natural implementation of coroutines via thin attributes, the undo/1 and some little support of the interpreter by a goal injection queue. I will post about this soon somewhere else.
Bye
(*)
https://www.complang.tuwien.ac.at/ulrich/iso-prolog/prologue
One possible solution would be to use the term-expansion mechanism provided by some Prolog systems and Logtalk to rewrite calls to e.g. the freeze/2 predicate to do the extra steps you want. One must be careful, however, to not expand a call to a predicate into another goal that calls the same predicate as goal-expansion is recursively applied until a fixed-point is reached. The Logtalk implementation of the term-expansion mechanism makes it easy to avoid this trap (with the additional advantage of portability as you can use Logtalk with most Prolog systems) by using a compiler bypass control construct, {}/1. A silly example would be:
:- object(my_expansions,
implements(expanding)).
goal_expansion(
freeze(Var,Goal),
( write('If you instantiate me, I will run away!\n'),
{freeze(Var,Goal)}, % goal will not be further expanded
write('Bye!\n')
)
).
:- end_object.
This object can then be used as an hook object for the compilation of source files containing calls to freeze/2 that you want to expand. Something like (assuming that the object above is saved in a file with the name my_expansions.lgt and that the source file that you want to expand is named source.lgt):
?- logtalk_load(my_expansions), logtalk_load(source, [hook(my_expansions)]).
For full details see the Logtalk documentation and examples.
There might be a clean way that I'm not aware of doing the same using the a Prolog system own term-expansion mechanism implementation. Anyone?

How to find facts that do not have contribution in goal

I'm trying to write a program that can check if the student program can fulfill a certain goal or not. I can do that part. Now, I want to check if the student program actually contains unnecessary code or not. For solving this case, I think I need to know if the student program contains facts that do not contribute to the specified goal. However, I cannot figure it out, how to find facts that do not contribute to the goal.
To make it easier to understand, let's consider a simpler example. In this example, the specified goal is: is john the grandfather of tomy?
father(john, jim).
father(jim, tomy).
father(john, david).
father(bruce, anne).
mother(mary, jim).
grandfather(A,B) :- father(A, X), father(X,B).
goal:- grandfather(john, tomy).
Actually the goal can be satisfied by the following facts only:
father(john, jim).
father(jim, tomy).
And the things that I want to know is which facts that actually do not contribute to the goal. The answer would be all the following facts:
father(john, david).
father(bruce, anne).
mother(mary, jim).
Any help is really appreciated.
Thanks
Your question cannot be directly answered in Prolog, but you can answer it manually by using a failure-slice. Simply add false goals into your program and always test whether goal still succeeds. Here is the minimal program I obtained.
father(john, jim).
father(jim, tomy).
father(john, david) :- false.
father(bruce, anne) :- false.
mother(mary, jim) :- false.
grandfather(A,B) :- father(A, X), father(X,B).
goal:- grandfather(john, tomy).
Every time you insert a goal false into a pure, monotonic program, you know for sure that the set of solutions is reduced (or stays the same). So finding such a slice involves about as many trials as there are places to set such goals. Sometimes you might want to add goals X = term to narrow down the program even further.
Failure slices are particularly useful when you want to understand the termination properties of a program, see failure-slice for more.
Unbelievably, there is a partial solution to this problem here. To reproduce the relevant portion here is substantial code, so let me make it clear that this is not my own work, I am just including the work here in case the website above goes missing in the future.
First, you need a meta-circular interpreter:
mi_circ(true).
mi_circ((A,B)) :-
mi_circ(A),
mi_circ(B).
mi_circ(clause(A,B)) :-
clause(A,B).
mi_circ(A \= B) :-
A \= B.
mi_circ(G) :-
G \= true,
G \= (_,_),
G \= (_\=_),
G \= clause(_,_),
clause(G, Body),
mi_circ(Body).
This works for \=/2 and clause/2. To generalize this pattern to all built-in predicates, we can use predicate_property/2 to identify them as such for calling them directly:
provable(true, _) :- !.
provable((G1,G2), Defs) :- !,
provable(G1, Defs),
provable(G2, Defs).
provable(BI, _) :-
predicate_property(BI, built_in),
!,
call(BI).
provable(Goal, Defs) :-
member(Def, Defs),
copy_term(Def, Goal-Body),
provable(Body, Defs).
This gives you a reified meta-interpreter, meaning you can pass provable/2 a goal and a set of definitions and it will tell you whether the definitions supplied are sufficient to prove the goal. I bet you can taste how close we are to the final solution now!
With the following additional definitions, we can use this MI to identify redundant facts in some predicate definitions:
redundant(Functor/Arity, Reds) :-
functor(Term, Functor, Arity),
findall(Term-Body, clause(Term, Body), Defs),
setof(Red, Defs^redundant_(Defs, Red), Reds).
redundant_(Defs, Fact) :-
select(Fact-true, Defs, Rest),
once(provable(Fact, Rest)).
This is using select/3 to portion out one definition at a time and see if the predicate is still provable. By doing that across all the definitions you can get the set of all unnecessary rules.
Given the definitions:
as([]).
as([a]). % redundant
as([a,a]). % redundant
as([A|As]) :-
A = a, % test built-in =/2
5 is 2 + 3, % test built-in is/2
1 > 0, % test built-in >/2
as(As).
we can ask for facts which are deducible from all (respective) remaining clauses and hence redundant:
?- redundant(as/1, Reds).
Reds = [as([a]), as([a, a])]
Alas, this does not work out-of-the-box on your problem, but I do think that with some study you could find a way to apply this technique to it and come up with something. For instance, you could create a meta-interpreter that takes a list of facts to check and perform the same sort of remove-one-then-prove loop to find them.
Hope this helps and is at least interesting.
Another option is to modify and use a unit testing framework that does predicate clause coverage. Define a unit test with the goal for which you want to find out which clauses don't contribute to it. The modifying bit, if necessary, will be to modify the coverage report to also identify those clauses. Just as an example of what I mean, in case it's not clear, consider the following output of the Logtalk lgtunit tool using one of the examples in the Logtalk distribution:
?- {ack(tester)}.
%
% tests started at 2013/6/5, 19:54:9
% running tests from object tests
% file: /Users/pmoura/logtalk/examples/ack/tests.lgt
% ack_1: success
% ack_2: success
% ack_3: success
% 3 tests: 0 skipped, 3 passed, 0 failed
% completed tests from object tests
% ack: ack/3 - [1,2,3] (3/3)
% 1 unit declared in the test file containing 3 clauses
% 1 unit covered containing 3 clauses
% 3 out of 3 clauses covered, 100,000000% coverage
% tests ended at 2013/6/5, 19:54:9
%
true.
The line:
% ack: ack/3 - [1,2,3] (3/3)
shows which clauses were used by the three unit tests for the ack/3 predicate.

Prolog - how to check if a predicate succeeds more than once

I have a database of facts like this:
li(a,2).
li(b,3).
li(b,1).
li(c,2).
li(d,1).
li(d,1).
I need to write a predicate more(+Let) that succeeds if it exists more than one fact li(Let,_).
For example the queries more(b) and more(d) will succeed, but more(a) and more(c) will not.
My idea was to check if li(Let,_) succeeds more than once, but I do not know how to do it.
Try findall/3:
findall(X, li(d,X), L), length(L,N), N>1.
Abstracting the d out and making a predicate is trivial. Right? :)
If you don't want to use any of the predicates like findall, you can change the representation of your knowledge - bring it down one level, so to speak:
my_knowledge(li, [a-2,b-3,b-1,c-2,d-1,d-1]).
and then you can use SWI Prolog's predicate select/3 to handle it:
select_knowledge(kn, key, R):-
my_knowledge(kn,L),
select_key(L,key,R).
select_key(L,K,R):-
select(K-X,L,L1) -> R=[X|R1], select_key(L1,K,R1)
; R = [].
You can rewrite the last predicate as basic recursion over lists, and then tweak it to stop after getting first N results.
more_than_once(Goal) :-
\+ \+ call_nth(Goal,2).
With call_nth/2 as defined in this answer.
The big advantage of this solution compared to the other solutions proposed is that it will succeed rapidly even if there is a very large sequence of answers. In fact, it will even succeed for an infinite sequence of answers:
?- more_than_once(repeat).
true.
?- more_than_once(between(1,100000,_)).
true.
(The implementation of call_nth/2 uses some non-standard, low-level built-ins of SWI. It is possible to avoid that, but with even more headache.)
SWI-Prolog has library(aggregate).
:- [library(aggregate)].
more(Key) :- aggregate_all(count, li(Key, _), C), C > 1.
test:
?- more(b).
true.
?- more(a).
false.
It's not very easy to learn, but useful to handle such common tasks. If you have a very large code base, then findall (and aggregate as well, that uses findall inside) could be inefficient, building a list only to count its elements.
Then you could use a side effect based predicate: in this related answer you'll find such utility. For max efficiency, see the comments, where is explained how to use nb_setval/nb_getval...

Resources