Writing Circle Area in ECLiPSe-CLP has Error - prolog

I write a predicate for calculating Circle Area by EClipse-clp.
circle(R) :- S is 3.14*R^2, write(S).
it has following Error:
calling an undefined procedure circle(R) :- S is 3.14 * R^2, write(S) in module eclipse

This is really very basic. You have to distinguish
Definitions - this is your program code, consisting of predicate definitions, which in turn are made up of facts and rules. Logically, this is where you define what is true.
Queries - this is where you call your program. Logically, you ask whether something is true, and how.
Definitions are usually loaded/compiled from a source file. Queries are usually typed into the query prompt. You seem to be typing a definition into the query prompt.

Related

Which way to store facts, apple vs exists(apple) is more idiomatic?

I am trying to develop a "simplest" prolog program.
Method 1
Conceptually, the program creates a set of facts which are stored in the database, to be queried later.
% simple facts
apple.
banana.
orange.
cherry.
The database can be queried as expected.
?- apple.
true
?- mango.
procedure `mango' does not exist
Method 2
Most textbooks which teach prolog would start such a "simplest" program using predicates, something like:
% simple facts
exists(apple).
exists(banana).
exists(orange).
exists(cherry).
The queries would then change in nature to testing whether the predicate can be satisfied, eg:
?- exists(apple).
true
?- exists(mango).
false
Question:
Is Method 1 an incorrect use of prolog? If so, why?
In my understanding, prolog is testing whether queries can be shown to be true, and to do this the database is searched. My doubt is raised by the error "procedure `mango' does not exist".
I think you are focusing on a distinction between "facts" and "predicates" which does not really exist; apple. is apple(). a predicate with no body and no arguments. The following shape:
name(argument1, argument2) :-
n2(arg3),
n3(arg4).
says that "name holds for the given arguments if n2 and n3 hold for their arguments", i.e. name only holds in certain conditions. Take the conditions away and you get:
name(argument1, argument2).
Now there are no conditions where it can fail, so it says "name holds for the given arguments". It always holds, it's like an unchanging fact, but "fact" is not a different kind of thing in Prolog, it's still a term with a functor and arity which can be called, it's just that the body of code to check is effectively true and nothing else.
Take the arguments away and you get:
name.
"name holds". It's similar to name()., no arguments.
The way Prolog is implemented, these are close to functions, procedures, subroutines in other languages - they are not the same, but Prolog looks through your code for one with a matching name (functor) and matching number of arguments (similar to method overload resolution in other languages), and calls it with the given arguments and sees whether it holds or not. If it cannot find a matching name and number of arguments, you get the "procedure does not exist" error.
In typical Prolog usage, the style name(argument1, argument2) is used so that "name" tries to describe a logical relation between the arguments, and the arguments are the data being related. e.g. length(List, Quantity) tries to explain that List is related to Quantity through the relation of length.
With method 2 you can extend it to:
exists(apple).
exists(crabapple).
exists(concrete).
food(apple).
food(crabapple).
food(snozzcumber).
edible(apple).
edible(snozzcumber).
and then ask for all things which exist, all foods, all edible things, or combinations like foods which are fictional and edible, things which exist but are inedible, etc. With method 1 you can say that apple holds, but you can't easily use it as data, can't easily query for all things which exist, can't easily change the code to describe that apple exists and is edible. With method 2 you can ask ?- exists(X). and have Prolog fill in X and tell you that apple exists. You can't easily do that with method 1.
If you put the data in place of the name (functor) that's like storing food by using an empty text file named 'apple.txt' and an empty text file named 'banana.txt' and so on, instead of putting them in a single file exists.txt. It's not a syntax or logical error to do this, if there is a reason you want to do it like that then you can, so it's hard to call it strictly "incorrect". Also like using a SQL database and making a table 'apple' and a table 'banana' and so on, instead of putting them in a table 'fruit'. Like having a bookshelf with a book named 'apple' and a book named 'banana' and so on, instead of one book named 'Fruits of the World'. You can do that, it's not incorrect to name a book "apple", but it's not a good way to use books to store lists of fruit.
If you specifically want something for codegolf where shortness trumps all other concerns then yes, fine. But it is going against the grain, against the normal use, it limits what you can do and it's not how Prolog was built to be used. It's also hard to describe something with fewer characters as "simpler" if it means a weird, limited, non-standard way of doing things.
The predicate exists/1 exists, the predicate apple/0 exists, the predicate mango/0 does not exist.
The query exists(apple). successfully reports true ("succeeds" in the Prolog vernacular), the query exists(mango). successfully reports false ("fails" to be proven, in the vernacular), the query apple. successfully reports true and the query mango. fails to execute because the predicate mango/0 does not exist.
So we can say that apple "exists", mango does not "exist", apple/0 exists, but mango/0 does not exist.
However, (in SWI Prolog),
11 ?- mango.
ERROR: toplevel: Undefined procedure: mango/0 (DWIM could not correct goal)
12 ?- [user].
:- dynamic(mango/0).
|: ^Z
true.
13 ?- mango.
false.
So you can work with your 1st method too, if you declare all the predicates of interest as dynamic.

Visual Prolog error c502: The expression does not produce a value

I am trying to translate a simple Turbo Prolog problem to Visual Prolog 7.1
The original Turbo Prolog code is the following.
DOMAINS
s=string sl=s* sll=sl*
PREDICATES
select(sl,s,sl)
solve(sll)
CLAUSES
select([A|B],A,B).
select([A|B],C,[A|D]):- select(B,C,D).
solve([["Anna",A,A],["Kate",Vp,Vt], ["Natasha",Np,"green"]]):-
select(["white","green","blue"],A,ColPl),
select(["white","blue"],A,[Vt]), Vt<>"white",
select(ColPl,Vp,[Np]), Vp<>"white", Np<>"green".
And its resulting list is outputted with solve(Out) with provides a correct result to the Turbo Prolog console.
When trying to translate this to Visual Prolog, I get error c502 in line 33.
implement main
open core
constants
className = "main".
classVersion = "".
domains
s=string.
sl=s*.
sll=sl*.
%
class predicates
select:(sl,s,sl) nondeterm anyflow.
solve:(sll) nondeterm anyflow.
%
clauses
%
select([A|B],A,B).
select([A|B],C,[A|D]):- select(B,C,D).
%
solve([["Anna",A,A],["Kate",Vp,Vt],["Natasha",Np,"green"]]):-
select(["white","green","blue"],A,ColPl),
select(["white","blue"],A,[Vt]), Vt<>"white",
select(ColPl,Vp,[Np]), Vp<>"white", Np<>"green".
clauses
classInfo(className, classVersion).
clauses
run():-
console::init(),
%ERROR AFTER THIS LINE
stdIO::writef("%", solve(Out)),fail().
end implement main
goal
mainExe::run(main::run).
What I get from this error is that solve(Out) does not give anything to print. What I do not know is how to change the code to produce something to print.
I am a beginner in Prolog and I cannot figure out how to fix this problem and Google is not much of a help either, this seems to be very obscure problem.
Thank you!
I'm not familiar with Visual Prolog, but could you rewrite the offending line as:
solve(Out), stdIO::writef("%", Out),fail().
and try again?
Remember that predicates are not functions like in other programming languages; they do not have a return value.
EDIT to answer comment: a procedure predicate should succeed exactly one time. Here, main is calling your solve function which my fail or succeeds several time. To ensure that, you can try to wrap the call to solve into another predicate:
wrap_solve(S) :- solve(S), !.
wrap_solve([]).
The cut after the call to solve should ensure that you get only one solution if it succeeds.
If there's no solution (i.e., the call to solve fails), then the second clause will give a default value (an empty list in that case).
In main, you should call wrap_solve instead of solve.

disjunctive syllogism in prolog

I am using swi-prolog. I want to model following statements in program.
"Either a or b is criminal. b is not criminal."
After modeling these statements. following query should work.
?-c(X).
X=a.
But,
when I wrote above statements in prolog:
c(a);c(b).
not(c(b)).
this code does not compile and shows error:
No permission to modify static procedure `(;)/2'
How to model above two statements in prolog?
afaik Prolog does not work this way. It tries to match your expression with all statements. So if you want to model "a is a criminal and b is not", then you can write
criminal(a).
not(criminal(b)).
but you can't say criminal(b) and in the next line not(criminal(b)), because this would lead to a contradiction.
the second line of my code ('not(criminal(b))') is actually redundant, because if Prolog doesn't find any matches of your term it will result in false, and backtrack for another solution. This means that you can simply omit all facts of not-criminals in this case.
you can then just ask Prolog which atoms it knows as criminals:
criminal(X).
and it will clearly tell you that
X=a.
whereas b is not part of the solution.

I want to create dynamic facts in prolog

I wrote the following simple code, and I expect that when I write 'male.', this code ask me once "is it male?" and if i input 'No' it write on screen "she is female".
male :- ( print('is it male ? '),read(yes)) -> true; asserta( not(male)),female.
female:- not(male),print('she is female').
not(P) :- (call(P) -> fail ; true) .
but this code has following error:
uncaught exception: error(permission_error(modify,static_procedure,not/1),asserta/1);
the error in swi-prolog is :
ERROR: asserta/1: No permission to modify static_procedure `not/1'
As gusbro said, not/1 is a predefined static procedure (and therefore it is not a good idea to use the same name). However, this is not the reason you get the error in swi-prolog as you can overwrite the standard definition:
?- assert(not(42)).
true.
?- not(42).
true.
the problem is that you have already defined not/1 in your code and, when you do not declare a predicate explicitly as dynamic, swi-prolog will assume that it's static and will not allow you to change it.
You can declare it as dynamic by inserting this line in your code:
:-dynamic(not/1).
I think that this will not solve the problem in other prolog implementations (eg gnu-prolog) as the error message says permission_error(modify,static_procedure,not/1); in any case it is highly recommended to change the name.
By the way, it would be simpler and cleaner to simply test what the argument is and print the corresponding message. If, however, you want to create something more complex (using a state maybe) you could use global variables since they are more efficient that assert/retract.

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