Trouble defining new operator - prolog

I'm trying to define an infix operator but I keep getting errors. I'm using GNU Prolog 1.4.
I tried this:
[user].
op(35, xfx, =>).
ctrl-D
But got the error "native code procedure op/3 cannot be redefined (ignored)"
I also tried op(35, xfx, '=>'). and got the same error, and tried doing it without typing in [user]. first, but when I tried to actually use the operator I got an existence_error.

yup you need to run the predicate instead of defining it. To do that just insert :- before your op/3 call.

Related

Prolog - 'unknown clause' error message when asking for user input when using PIE (Prolog Interface Engine)

I'm writing code for a simple program that outputs any phrase that the user inputs. Here's my code so far:
input():-
read(X),
nl,
write(X).
Here's the output:
input().
input().
Unknown clause found read(X$0)
Execution terminated
No solutions
Here's my desired output:
input().
input().
hello
hello
Note: In a comment the OP noted this was originally done using PIE (Prolog Interface Engine)
Your problem is that you are using read/1 which expects a Prolog term. Prolog terms are not strings that can be of any form, Prolog terms end with a period (.). So in your example input(). works because it ends with a period, hello does not work because it does not end with a period.
Using your query
?- input().
|: input().
and entering input(). works
input()
true.
?- input().
|: hello
|: .
entering hello does not work right away as indicated by the second prompt |: but then entering the . completes the Prolog term and works.
hello
true.
--
Here is demo of your code, slightly modified running on SWISH.
When I ran your code with SWI-Prolog installed on my laptop it worked with input() as the predicate. When I tried the same with SWISH it complained, but changing the predicate from input() to input solved that problem.
Now knowing that you are not using a common Prolog such as SWI-Prolog and seeing the error message
Unknown clause found read(X$0)
tells me that PIE does not have read/1, I did a quick check of some tutorials for PIE and could not find any use of read/1. The obvious conclusion is that PIE does not support read/1 and if you want to use read/1 while learning Prolog you will have to use something that does, e.g. SWI-Prolog, SWISH, GNU Prolog

Prolog: subsets facts not working

I've never written in Prolog before. I have to provide facts so that when it runs it displays:
?- subset([a,b],[a,c,d,b]).
true.
?-include([],[a,b]).
true.
So far, I've written this:
subset([],_Y).
subset([X|T],Y):- member(X,Y),subset(T,Y).
But include doesn't work when I write include([],[a,b]). . It shows this:
ERROR: toplevel: Undefined procedure: include/2 (DWIM could not correct goal)
Any help would be appreciated. Thanks
You get the error because you didn't define the predicate include/2. Your given example looks like include/2 should be describing the same relation as subset/2. So you can either rename your definition from subset/2 to include/2 and then run the query or you can use subset/2 to define include/2:
include(X,Y) :-
subset(X,Y).
Note that in order to use member/2 you have to use library(lists). However, in some Prolog systems (e.g. SWI) this library includes a predicate subset/2 thus leading to a warning when you consult your source file:
Warning: ...
Local definition of user:subset/2 overrides weak import from lists
If you want to implement your own version of subset/2 anyway and not get this warning, you can rename your predicate or not use library(lists) and implement your version of member/2, for example:
subset([],_Y).
subset([X|T],Y) :-
element_in(X,Y),
subset(T,Y).
element_in(X,[X|_]).
element_in(X,[Y|Ys]) :-
dif(X,Y),
element_in(X,Ys).

"operator expected after expression" when using dynamic openList/1

I'm trying to call the following at the top of my prolog file.
:- dynamic openList/1, dynamic closedList/1.
But this results in the following syntax error.
syntax error: . or operator expected after expression
I can't figure out what I'm doing wrong?
Thanks in advance.
In ISO Prolog only the following forms are legal:
:- dynamic(openList/1).
:- dynamic(closedList/1).
or
:- dynamic([openList/1,closedList/1]).
or (strangely, and not recommended)
:- dynamic((openList/1,closedList/1)).
Some Prologs will also allow (not portable)
:- dynamic openList/1, closedList/1.

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.

Declaring a predicate dynamic in gprolog

I have this code in Prolog:
dynamic(player_at/1).
player_at(house).
goto(X) :- retract(player_at(house)), assert(player_at(X)).
But I still get this error:
uncaught exception: error(permission_error(modify,static_procedure,player_at/1),retract/1)
when I execute goto(foo).
I've read the dynamic documentation, but I can't figure out how to use it, at least in gprolog. Am I missing something?
Fix the first line by prepending :-:
:- dynamic(player_at/1).
Without :- the line would dreefine predicate dynamic/1, instead of executing the existing dynamic predicate.
Other prolog implementations (but not gprolog) support this as well:
:- dynamic player_at/1.

Resources