I need to check call a predicate automatically at the consult or start of pl.
Is there a such code to this?
Directives are executed during source consult. Then when Prolog load a file in which appear (for instance)
...
:- writeln(hello).
:- writeln(world).
...
will write the message.
A special directive is initialization/1:
Call Goal after loading the source file in which this directive appears has been completed.
Related
I'm new to Prolog, please just don't blast me.
Whenever i had to consult a prolog database i used the predicate consult/1 :
consult(:File)
Now, i noticed that there exist also the predicate open
open(+SrcDest, +Mode, --Stream, +Options)
that allows to read a database.
Apart the possibility to modify the database, not allowed by consult, which are the differences between consult and open (maybe in the extensions of the files that each predicate can open, or maybe because consult reads fact and rules, while with open we can read terms) ?
Using consult/1 seems to be quite similar to use ?- [filename]. Using consult/1 in your program, you can have access to all the facts and predicates written into the file. So for instance if you have a file data.pl like this:
fact(a).
fact(b).
fact(c).
hello:-
writeln('hello').
You can create a file, test.pl and use all the facts and predicate of data.pl:
run:-
consult(prova),
findall(A,fact(A),L),
hello,
writeln(L).
?- run.
hello
[a,b,c]
true.
Moreover, consult seems to accept only .pl file with a dictionary sructure. On the other hand, with open/3, you can access each type of file and read also char by char, but you cannot access the predicates and facts written into the file:
run:-
open('prova.pl',read,Str),
findall(A,fact(A),L),
hello,
writeln(L).
?- run.
ERROR: Undefined procedure: fact/1
Obviously, with open/3 or open/4 you can create, write into files and so on.
In SWI-Prolog, I want to load differente files based on input in a predicate, and use rules defines in this file in this predicate, but it didn't work. I wonder if there's a way to load file that rules in this file could take effect immediately.
The thing I want to achieve is like:
rule.pl:
classify(X,Y):-X('1'),Y('2').
main.pl:
RuleFile('rule')
initClassify(X,Y):-load_files(RuleFile),classify(X,Y).
When I call initClassify/2, it complained that classify/2 undefined procedure.
I am trying to perform the following term_expansion with swipl:
a(asda).
a(astronaut).
term_expansion(a(X),b(X)).
But it does not work, i.e. there is no b/1 consulted. I have tried a few variations:
term_expansion(a(X),[b(X)]).
user:term_expansion(a(X),b(X)).
user:term_expansion(a(X),[b(X)]).
user:term_expansion(user:a(X),[user:b(X)]).
None of which works. What is the problem?
As explained by #mat, you need to define the term_expansion/2 predicate before the clauses you want to expand are loaded. Also, the term_expansion/2 predicate is a multifile and dynamic predicate defined for the user pseudo-module. Thus, you should write:
:- multifile user:term_expansion/2.
:- dynamic user:term_expansion/2.
user:term_expansion(a(X), b(X)).
This will ensure that your expansion code will work if you move it into a module.
If portability to other Prolog systems with a term-expansion mechanism (which, btw, is far from standard), than consider moving the term-expansion code to its own file, loaded before the source files you want to expand.
Case: I have a file, solution.pl, where I want to use the rules of another file (this is the definition of the program, not up to me, but I think it's somewhat common).
So I'm using Ciao Prolog and the syntax seems to be ensure_loaded('c:/Path').
but when I try to use the rules of the other file, it tells me he doesn't know what rule I'm trying to use.
On the other hand, if I write on the console that same lane, and then query again, it does work.
So I was wondering maybe the syntax for doing it on the console and on a file are different??
Could someone tell me a step by step so I can figure it out if I'm missing something? What I'm doing right now is loading the program as I would do with smaller programs, then try to query rules of the file included in the ensure_loaded command. And as I said, it does seem to work if write the command outside of the program.
in solution.pl, try
:- ensure_loaded('c:/Path').
or, if the source in c:/Path has a module directive - that is, it begins with :- module(name, [exported/arity, ...]).
:- use_module('c:/Path').
In my program I have a dynamic clauses, they works fine, but when I closing my program, they are disappears.
I've tryed that
saveState :-
write_pl_state_file('backup.dat').
loadState :-
file_exists('backup.dat'),
read_pl_state_file('backup.dat'); !.
but this is not works.
Is there a way to save this databse to a file?
The predicates write_pl_state_file/1 and read_pl_state_file/1 are connected with the information/state that affects parsing of terms, i.e. operator definitions, character conversion Prolog flags, etc.
So that is part of your solution (perhaps), but more fundamentally you wish to save the dynamic clause definitions, probably in a form that allows you to reinstate them by consulting a file.
The predicate listing/0 does something like this, but it displays the dynamic clauses to the "console", not to a file. Probably you want to use the underlying predicate portray_clause/2, which does allow redirecting output to a file (stream).
The author Daniel Diaz noted a slight change (adding a newline to end of output) for portray_clause/2 in recent release notes for version 1.4.0, so you may want to make sure you've got the latest version for the sake of legibility.
Added:
It appears that starting with version 1.3.2 GNU Prolog supports sending listing/0 output to the current stream (rather than just to the console as in 1.3.1 and earlier).
Here's a test case:
| ?- assertz(whoami(i)).
| ?- assertz(whoami(me)).
| ?- assertz(whoami(myself)).
which creates three clauses (facts) for a dynamic predicate whoami/1.
I then created a file myClauses.pl with the following query:
| ?- open('myClauses.pl',write,S), set_output(S), listing, close(S).
Once the stream S is closed, current output is reset to the console.
You will find that the file myClauses.pl contains a blank line followed by the three clauses, so that the source code is in proper form to be consulted. However I'm having a problem with the consult/1 predicate (and its File -> Consult... menu equivalent) in my newly installed GNU Prolog 1.4.0 under Windows. The compilation works from the command line and produces a byte-code file that load/1 can correctly handle in the console, so there's some small problem in how things are set up. I'll post a further note when I get that squared away, having sent in a bug report. I've not tried it yet under Linux.
You can use current_predicate/1 or predicate_property/2 to access predicates, and clause/2 to access the clauses for a predicate.
Then you can write a save utility by using that information.