How use Goal in SWI-Prolog - prolog

In TurboPrologwe can use next construction:
goal:
father('Tom', X).
How use same in SWI-Prolog?

If I recall what goal does, I suggest to use the ISO-Prolog built-in initialization/1:
Call Goal after loading the source file in which this directive appears has been completed.
:- initialization((father('Tom', X), writeln(X))).
I've added a visualization of the value obtained - if any. Also some error handling should be added...

And how we can call 2 or more Goal?
Next code call error:
:- initialization(
(grandmother('Sarah', X), writeln(X)),
(father('Tom', Y), writeln(Y))
).

Related

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).

turning off Redefined static procedure in prolog

anyone of you could tell me how to turn off "Redefined static procedure" warnings?
I red online documentation of swi-prolog and i found this predicate no_style_check(ultimate) that in principle should turn off these warnings, but when i execute this predicate
main:-
no_style_check(singleton),
no_style_check(discontiguous),
no_style_check(multiple),
require,
test_all.
i received this error
ERROR: Domain error: style_name' expected, foundmultiple'
Anyone knows an alternative way to do this or could tell me why i receive this error ?
Thanks in advance!
Prolog is a pretty loosey-goosey language, so by default it warns you when you do certain things that are not wrong per se, but tend to be a good indication that you've made a typo.
Now, suppose you write something like this:
myfoo(3, 3).
myfoo(N, M) :- M is N*4+1.
Then from the prompt you write this:
?- asserta(myfoo(7,9)).
ERROR: asserta/1: No permission to modify static procedure `myfoo/2'
ERROR: Defined at user://1:9
What's happening here is that you haven't told Prolog that it's OK for you to modify myfoo/2 so it is stopping you. The trick is to add a declaration:
:- dynamic myfoo/2.
myfoo(3, 3).
myfoo(N, M) :- M is N*4+1.
Now it will let you modify it just fine:
?- asserta(myfoo(7,9)).
true.
Now suppose you have three modules and they each advertise themselves by defining some predicate. For instance, you might have three files.
foo.pl
can_haz(foo).
bar.pl
can_haz(bar).
When you load them both you're going to get a warning:
?- [foo].
true.
?- [bar].
Warning: /home/fox/HOME/Projects/bar.pl:1:
Redefined static procedure can_haz/1
Previously defined at /home/fox/HOME/Projects/foo.pl:1
true.
And notice this:
?- can_haz(X).
X = bar.
The foo solution is gone.
The trick here is to tell Prolog that clauses of this predicate may be defined in different files. The trick is multifile:
foo.pl
:- multifile can_haz/1.
can_haz(foo).
bar.pl
:- multifile can_haz/1.
can_haz(bar).
In use:
?- [foo].
true.
?- [bar].
true.
?- can_haz(X).
X = foo ;
X = bar.
:- discontiguous does the same thing as multifile except in a single file; so you define clauses of the same predicate in different places in one file.
Again, singleton warnings are a completely different beast and I would absolutely not modify the warnings on them, they're too useful in debugging.

Accessing SWI-Prolog libraries from Logtalk

I'm having a lot of fun using Logtalk, but ran into an issue using phrase_from_file. Specifically, my case looks something like this:
:- object(scan_parser).
:- public(scanlist//1).
scanlist([Scan|Scans]) --> scan(Scan), dcg_basics:blanks, scanlist(Scans).
scanlist([]) --> [].
:- public(scan_file/2).
:- mode(scan_file(+filename, -scans), one).
scan_file(Filename, Scans) :- pio:phrase_from_file(scanlist(Scans), Filename).
...
:- end_object.
The trouble is all in that call to phrase_from_file. It's unable to find scanlist, presumably because it is local to this object, so I get this error:
?- scan_parser::scan_file('input.txt', Scans).
ERROR: phrase/3: Undefined procedure: pio:scanlist/3
But, if I try to aggrandize it with a module reference like so:
scan_file(Filename, Scans) :- pio:phrase_from_file(::scanlist(Scans), Filename).
I get this error:
?- scan_parser::scan_file('input.txt', Scans).
ERROR: phrase/3: Undefined procedure: pio: (::)/3
Same if I use pio:phrase_from_file(this::scanlist(Scans), Filename) or pio:phrase_from_file(scan_parser::scanlist(Scans), Filename). If I use a single colon instead in emulation of SWI's module facility, I get messages like ERROR: phrase/3: Undefined procedure: scan_parser:scanlist/3.
I assume that the problem here is that SWI's PIO library is trying to construct something to hand to phrase and it's just not intelligent enough. But this is something that comes up for me a lot, using phrase_from_file/2, and I'm sure there will be other times I want to excavate something from SWI's library and borrow it. What's the right way forward? I'd like to preserve the encapsulation of Logtalk as much as possible.
Thanks!
I'm designing a general solution for Logtalk 3.x to support Prolog module meta-predicates that take closures as meta-arguments. Meanwhile, can you try the following (ugly) workaround:
% ensure the module is loaded
:- use_module(library(pio)).
:- object(scan_parser).
% override the non-standard meta-arguments declarations
:- meta_predicate(pio:phrase_from_file(2,*)).
:- public(scanlist//1).
scanlist([Scan|Scans]) --> scan(Scan), dcg_basics:blanks, scanlist(Scans).
scanlist([]) --> [].
:- public(scan_file/2).
:- mode(scan_file(+filename, -scans), one).
scan_file(Filename, Scans) :- pio:phrase_from_file(user:scan_parser_scanlist(Scans), Filename).
{scan_parser_scanlist(Scans, A, B)} :-
phrase(scanlist(Scans), A, B).
...
:- end_object.
I cannot test as you only posted part of the object code.

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!

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