How to check for empty Arguments in Prolog? - prolog

I'm new to prolog and could use some help.
Currently, I have to make a program that concat the last character of two strings.
For example,
?- termCat(with,spaghetti,T).
T=hi
I was wondering how can I account for one of the arguments being nonexistant.
For instance I'm hoping to catch something like this...
?- termCat( , spaghetti,T).
T = i

I use this pattern for 'default arguments' (the C++ feature, kind of). Depending on your use case and Prolog system, you should adapt as required. Beware that var/1, nonvar/1, !/0 are impure builtins that could interfere in unexpected ways with the resolution process. The cut (that is, !/0) is implicit in ->/2.
termCat(X,Y,T) :-
(var(X) -> X=with;true),
(var(Y) -> Y=spaghetti;true),
etc etc.
In SWI-Prolog, you can require arguments are not free - for instance - using assertion/1 from library(debug):
:- use_module(library(debug)).
termCat(X,Y,T) :-
assertion((nonvar(X),nonvar(Y))),
etc etc.

Related

Using the prolog format predicate to print to file

Is it possible to use the prolog format predicate to print to file?
I have a table of data that I print to stdout using the format predicate, i.e.
print_table :-
print_table_header,
forall(range(1.0,10.0,0.1,N), print_row(N,L)).
%% print_row(L) :- take a list of the form, [a,b,c,d,e] and
%% print it to screen as a single row of tab separated float values (1DP)
print_row(N,L) :-
build_row(N,L),
format('~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~n', L).
print_table_header :-
format('~t~w~10+ ~t~w~10+ ~t~w~10+ ~t~w~10+ ~t~w~10+ ~n', ['N','N2','N3','N4','N5']).
would be nice to somehow reuse the code to print the same thing to file.
In addition to the other good answer (+1!), I would like to present a purer solution to such tasks.
The key idea is to make format/2 accessible within DCGs, and then to use a DCG to describe the output.
This is very easy, using the codes argument of format/3, provided by several Prolog implementations. All you need are the following short auxiliary definitions:
format_(Data, Args) --> call(format_dlist(Data, Args)).
format_dlist(Data, Args, Cs0, Cs) :- format(codes(Cs0,Cs), Data, Args).
The nonterminal call//1 calls its argument with two additional arguments that let you access the implicit DCG arguments, and this is used to describe additional codes via format/3.
Now, we can simply use the nonterminal format_//2 within DCGs.
For example, to describe a simple table:
table -->
row([a,b,c]),
row([d,e,f]).
row(Ls) --> format_("~t~w~10+~t~w~10+~t~w~10+~n", Ls).
Usage example and result:
?- phrase(table, Cs), format("~s", [Cs]).
a b c
d e f
Cs = [32, 32, 32, 32, 32, 32, 32, 32, 32|...].
Note that one last remaining format/2 is used to actually write the output to the screen.
However, everything else is free of side-effects and declaratively describes a table.
An important advantage of this method is that you can easily write test cases to see whether your tables are (still) correctly formatted. It is easy to reason about Prolog lists of codes (described with a DCG), but quite hard to reason about things that only appear on the terminal.
You can!
Consider the following extract of the SICStus Prolog documentation for format/[2,3]:
11.3.85 format/[2,3]
Synopsis
format(+Control, +Arguments)
format(+Stream, +Control, +Arguments)
Interprets the Arguments according to the Control string and prints the result on Stream.
The predicates format/[2,3] are widely supported across Prolog implementations.
However, as of right now, these predicates are not part of ISO Prolog.
I would write the output 'routines' with an additional parameter, a Stream, and then I would pass user while testing or printing to screen. See ISO predicates open/3, close/1 etc for stream handling...
Note that IO it's among the least 'declarative' areas of the language, because, for efficiency, an approach based on side effects is required...
SWI-Prolog has a builtin with_output_to, that would allows to reuse your existing code without adding a parameter. But since you tagged iso-prolog your question, you should really add the Stream parameter...

Is there a way to annotate the parameter and return value in Prolog?

parent(mel, joan).
parent(jane, betty).
parent(jane, tom).
parent(richard, adam).
parent(richard, rosa).
parent(joan, fran).
For example someone asks me to find all ancestors of a parent. I give him the code:
ancestor(P,C) :- parent(P, C).
ancestor(P,C) :- ancestor(P,P1), parent(P1, C).
But my friend still doesn't know how to use the predicate. Does he call it like
ancestor(richard, C) or ancestor(C, richard) ?
Is there a way to annotate that P is the parameter while C is the return value? And in a complex case, there will be predicates with different names, how should my user know which predicate is the final predicate he wants to use?
To help the human-readable meaning, you could add an extra predicate documenting the parameters as readable name/value pairs:
entry_ancestor_of(ancestor=P, descendent=C) :-
ancestor(P,C).
?- entry_ancestor_of(ancestor=richard, descendent=C).
C = adam .
Above, the suffix *ancestor_of* suggests param 1 is ancestor of param 2, so naming the predicate carefully can make it clearer.
Usually(convention), input parameters are the earlier parameters, and output parameters are later parameters, but where the predicate 'works both ways', ie. either could be input or output, this rule can't hold. This is the case for your predicate:
?- entry_ancestor_of(ancestor=X, descendent=adam).
X = richard .
Either parameter could be input or output, so there is no need to codify/explain them as such, although you might want to comment that it works both ways.
I would usually comment these 'flexible' predicates by putting an example of both of the above usages in a comment next to the predicate.
For entrypoint labelling, just do one or more of the following:
explicitly name the predicate as an entrypoint, as above
document using comments in the code which are the entrypoints
arrange the entrypoints in the same physical section with a comment
block saying that the predicates below are entrypoints.
Edit: Extra things re: coding guidelines / other answers.
In Coding guidelines for Prolog, section 3.8, it says 'For example, mother_of(A, B) is ambiguous;', so I gave bad advice on that.. perhaps acapelli's suggestion would be more useful on that.
In that document, also have a look at:
3.5 Choose sensible names for auxiliary predicates
3.8 Choose predicate names to help show the argument order
3.13 Decide whether predicate names should carry the types on which they operate
4.1 Begin every predicate (except perhaps auxiliary predicates) with an introductory comment in a well-defined format
The '?' system for identifying parameter types that will ness mentioned is on page 21.
a useful convention, sponsored for instance by Markus Triska, builds a predicate functor by joining the parameters 'names' - in a wide, applicable sense. Your example could be
parent_child(mel, joan).
...
ancestor_descendant(P, C) :- parent_child(P, C).
ancestor_descendant(A, D) :- ancestor_descendant(A, I), parent_child(I, D).
Also ISO-Prolog, and - for instance - SWI-Prolog library, attempt to follow this strategy.
For instance
atom_codes(Atom, Codes) :- ...
WRT to declare the type and status of arguments, some Prolog provide declarations - for instance Turbo Prolog, ECLiPSe, others... Sometime such declarations are required - usually to check correctness, often to speed up the computation.
SWI-Prolog offers 'just' structured comments, that IDE process automatically, and there has been a contribution aiming to exploit such declarations with runtime check.
Yes, with comments, and/or meaningful argument names,
% ancestor( ?Ancestor, ?Descendent).
ancestor(P,C) :- parent(P, C).
ancestor(P,C) :- ancestor(P,P1), parent(P1, C).
? means the argument can be used both as input (already set when the call is made), or for output (not yet set when the call is made).
The convention promoted in The Art of Prolog (I think) is that you place the name of the predicate after its first argument, to get at the intended argument ordering: P "is" ancestor C. Presumably "ancestor_of". But if you use that name, someone unfamiliar with that convention might read ancestor_of(P,C) as "ancestor of P is C", so it's a double-edged sword.

error while compling the metaprogram in prolog

I am trying to implement a meta-program in ECLiPSe Prolog, and here's the code that i have written -
:- dynamic go/1.
sol(true):- !.
sol((A,B)):- !, sol(A), sol(B).
sol(A):- clause(A, Body), sol(Body).
go(X):- X is 5.
Now when I query with sol(go(X)). , I get the error accessing a procedure defined in another module in clause(X is 5, _292) and it aborts. I tried clearing all toplevel modules and reopening ECLiPSe and then running, but still the same error.
What could be the reason?
Thanks!
Predicate p/1 is using the built-in predicate (is)/2. Note that X is 5 is a syntactically more convenient way of writing is(X,5). But your meta-interpreter is only expecting user defined predicates and the control constructs (',')/2 and true/0. If you want to handle (is)/2 you have to introduce a separate clause for it.
sol(X is Y) :- !, X is Y.
Within ISO Prolog, the goal predicate_property(Goal,built_in) can be used to test if Goal is a built-in predicate. This works in many systems like B, GNU, SICStus, SWI, XSB, YAP. So you can write:
sol(Bip) :- predicate_property(Bip, built_in), !, Bip.
In ECLiPSe this built-in is not directly available. You have to load a library. The index of the manual suggests to use library swi or quintus. For some (unclear) reason it is not part of the ECLiPSe library iso, yet it is ISO. So state
:- use_module(library(swi)).
in your file (or at the toplevel) first.
If you want a meta-interpreter to cover the full Prolog language you will have to handle all control constructs explicitly. Here they are - as defined in the standard (7.8 Control constructs).
true/0
fail/0
call/1
!/0
(',')/2
(;)/2 - disjunction
(->)/2
(;)/2 - if-then-else
catch/3
throw/1
Please be aware that only a few of them can be handled by directly calling the goal. Most of them must be handled explicitly!

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

How to verify if a rule exists in a prolog file clause database

I'm working on a college assignment where I must verify if a certain clause (as a fact or as a rule) exists in the current clause database.
The idea is to use a rule whose head is verify(+name, +arguments). This rule should be true if in the database exists another rule whose head is name(arguments)
Any help would be greatly appreciated...
Using call/1 is not a good idea because call/1 actually calls the goal, but you just want to find out if the fact/rule exists, and you don't want to wait after a long calculation that the call might trigger, and you don't want to have something printed on the screen if the called rule in turn calls e.g. writeln/1. In addition, you would want verify/2 to succeed even if the call failed (but the fact/rule is otherwise there).
As a solution, SWI-Prolog offers callable/1
callable(+Term)
True if Term is bound to an atom or a compound term,
so it can be handed without type-error to call/1, functor/3 and =../2.
Here are two version of verify/2, one using call/1 and the other using callable/1.
verify1(Name, Arguments) :-
Term =.. [Name | Arguments],
call(Term).
verify2(Name, Arguments) :-
Term =.. [Name | Arguments],
callable(Term).
father(abraham, isaac) :-
writeln('hello').
father(abraham, adam) :-
fail.
Are you familiar with the concept of unification? What you have to do is: just call a predicate that looks like the one you're trying to find.
So, say in your database is:
father(abraham,isaac).
Now you want to call something like:
verify(father,[abraham,isaac]).
Your predicate body will then have to contain a mechanism of calling father(abraham,isaac). which should then return true. Calling father(abraham,adam) should fail.
You will need two predicates for this: =../2 and call/2. If you are using SWI-Prolog, call help(=..). and help(call) from the interpreter's command line to access the documentation.
I hope I didn't spoil the assignment for you. You still have to find out what to do with partially instantiated predicates (so, say something like verify(father,[abraham,X]). on your own, but it shouldn't be hard from here.
Good luck.

Resources