Conversion from string to list in Prolog - bash

I'm trying to use a piece of software and I'm running into some problems.
It's worth noting that using university computers which have prolog preinstalled(OSX) or Windows computers the same piece of software works. While it does not work on my Linux/Ubuntu machine.
The software starts up with a bash script using this form:
echo "reset_statistics(off), specific_load_predicate(filename), tokenize(\"$2\", List), tex(List, $3)." | ./prolog-executable
The prolog executable is created using swipl -c and qsave_program/1
Now I found out the predicate tokenize is of the form:
tokenize([A|As], List) :- ...
So it takes a list as input, but the bash script provides a String.
Is it possible using some sort of prolog module or extension that would automatically make the conversion from string to list? Because the same code works on other computers.

SWI-Prolog unfortunately deviates from the Prolog ISO standard in that what is surrounded by double quotes is no longer a list of character codes.
To restore the compliant behaviour in this respect, use one of the following methods:
invoke SWI-Prolog with the --traditional flag
add :- initialization(set_prolog_flag(double_quotes, codes)). to your source file.
add :- set_prolog_flag(double_quotes, codes). to your ~/.swiplrc initialization file.
In fact, instead of going with lists of character codes, I recommend you take a different route altogether and adapt your programs to use lists of characters, which means that each character is represented by an atom. This has the great advantage that toplevel answers remain very similar to what appears in queries, and are in fact quite readable by themselves. You obtain lists of characters for example by putting:
:- set_prolog_flag(double_quotes, chars).
in your ~/.swiplrc initialization file. With the value chars, you get for example:
?- Cs = "hello".
Cs = [h, e, l, l, o].
I recommend you use this value, and adapt your existing programs to work with lists of characters. Long-term, I think this will be the the best and most widely used approach, which was historically also what double-quotes were meant to denote.
Until we get (back) there, you can use one of the methods above (i.e., switch to codes as an intermediate solution, to at least work around the problems introduced by SWI 7), then adapt your libraries to work with codes and characters, and then, at last, switch to characters.

Related

SWI-prolog semweb library processing of URI

Being new to prolog I am reading existing code (as well as trying to write some code). Having some prior background in semweb I started to play with it and see something that is confusing me. Example assertion:
?- rdf_assert(ex:bob, rdf:type, foaf:'Person').
I also did find the following in the documentation:
Remember: Internally, all resources are atoms. The transformations
above are realised at compile-time using rules for goal_expansion/2
provided by the rdf_db library
Am I correct in assuming that somehow the library is treating the three URIs as atoms? I thought that the compiler would treat this as module_name:predicate, but that does not seem to be the case. If that is true, could you please provide a simple example on how this could be done in prolog?
Thanks
Prolog is not a functional language. This implies 2+3 does not evaluate to 5 and is just a term that gets meaning from the predicate that processes it. Likewise, ex:bob is just a term that has no direct relations to modules or
predicates. Only predicates such call/1 will interpret this as "call bob in the module ex".
Next to that, (SWI-)Prolog (most Prolog's, but not all) have term expansion that allows you to rewrite the term that is read before it is handed to the compiler. That is used to rewrite the argument of rdf/3: each appearance of prefix:local is expanded to a full atom. You can check that by using listing/1 on predicates that call rdf/3 using the prefix notation.
See also rdf_meta

Workaround ensure_loaded/1 GNU Prolog?

Is there a workaround to make ensure_loaded/1 work
in GNU Prolog as it works in many other Prolog systems?
The goal is to have a preamble so that the rest of
code can use ensure_loaded/1 independent of whether which
Prolog system I use.
I tried the following:
:- multifile(term_expansion/2).
term_expansion((:- ensure_loaded(X)),
(:- atom_concat('<base>\\', X, Y),
include(Y))).
But the following query doesn't work:
:- ensure_loaded('suite.p').
The path calculation itself is not the issue of the question,
but the redefinition of a directive in GNU Prolog. There is
another directive that causes problems: meta_predicate/1. The
byte code crashes as follows:
Bye
A partial solution is:
ensure_loaded(File) :-
absolute_file_name(File, Path),
( predicate_property(_, prolog_file(Path)) ->
true
; consult(Path)
).
It assumes that the file defines at least one predicate but that's a sensible assumption. However, there's seems to be no way to override the native, non-functional, definition of the ensure_loaded/1 directive. A workaround would be to wrap the ensure_loaded/1 directive within an initialization/1 directive. For example:
:- initialization(ensure_loaded('suite.pl')).
Hence this being a partial solution as we're really defining an ensure_loaded/1 predicate, not a directive.
My current speculation is, that it is impossible with
the standard distribution of GNU Prolog 1.4.4. The
docu says:
The GNU Prolog compiler (section 4.4) automatically calls
expand_term/2 on each Term1 read in. However, in the current release,
only DCG transformation are done by the compiler (i.e.
term_expansion/2 cannot be used). To use term_expansion/2, it is
necessary to call expand_term/2 explicitly.
I also tried to inject some Prolog code for term_expansion/2
via the command line, but to no awail. Although the tool chain
has options such as -O, -L, -A that pass options to other tools.
There is not really an option that passes a Prolog text to the
pl2wam, in course of the execution of a consult/1 issued inside
the top-level.
At least this are my results so far.
Bye

Is it acceptable for a prolog procedure to work only one way?

I have a prolog program:
link(liverpool,preston).
link(liverpool,manchester).
link(preston,lancaster).
link(preston,manchester).
link(lancaster,carlisle).
link(lancaster,leeds).
link(carlisle,leeds).
link(manchester,leeds).
%checks to see if X is in the supplied list
inlist( X, [X|_]).
inlist( X, [_|Ys]) :- inlist( X, Ys).
merge([],L,L).
merge([H|T],BList,CList):-
inlist(H,BList),
merge(T,BList,CList).
merge([H|T],BList,[H|CList]):-
merge(T,BList,CList),
not(inlist(H,BList)).
Merge works if I call it like this:
merge([a,b,c],[d,e,f],Result). --> [a,b,c,d,e,f]
or more importantly, what it was designed to solve:
merge([a,b,c],[a,d,e,f],Result). --> [a,b,c,d,e,f]
but if I call merge like this:
merge(X,[d,e,f],[a,b,c,d,e,f]).
There is a stack overflow. Is this generally acceptable behavior for a function that is designed to work one way? Or is there some convention that functions should work in both ways?
Edit: merge works if you call it like this:
merge([a,b,c],X,[a,b,c,d,e,f]). --> [d,e,f]
First, you should not call these "functions". "Predicates" is the correct term.
It's generally desirable for Prolog predicates to work "both ways". But it's not always possible or worth the effort in a particular situation.
To inform about ways a predicate is intended to be used mode-declarations can be used. These declarations conventions are different from system to system. These declarations are mostly serve as a documentation for programmers and rarely used by compilers, but can be used by testing frameworks and other helper tools.
Examples of conventions for mode declarations:
SWI-Prolog: http://www.swi-prolog.org/pldoc/man?section=modes
ECLiPSe CLP: http://eclipseclp.org/doc/applications/tutorial003.html#toc10 (scroll to 2.7.3 Mode declaration)
Also there is a convention (described in "The Craft of Prolog", for example) that input parameters of a predicate come first, output parameters come last.

Saving GProlog database

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.

How to do case conversion in Prolog?

I'm interfacing with WordNet, and some of the terms I'd like to classify (various proper names) are capitalised in the database, but the input I get may not be capitalised properly. My initial idea here is to write a predicate that produces the various capitalisations possible of an input, but I'm not sure how to go about it.
Does anyone have an idea how to go about this, or even better, a more efficient way to achieve what I would like to do?
It depends on what Prolog implementation you're using, but there may be library functions you can use.
e.g. from the SWI-Prolog reference manual:
4.22.1 Case conversion
There is nothing in the Prolog standard for converting case in textual data. The SWI-Prolog
predicates code_type/2 and char_type/2 can be used to test and convert individual
characters. We have started some additional support:
downcase_atom(+AnyCase, -LowerCase)
Converts the characters of AnyCase into lowercase as char_type/2 does (i.e. based on the
defined locale if Prolog provides locale support on the hosting platform) and unifies the
lowercase atom with LowerCase.
upcase_atom(+AnyCase, -UpperCase)
Converts, similar to downcase_atom/2, an atom to upper-case.
Since this just downcases whatever's passed to it, you can easily write a simple predicate to sanitise every input before doing any analysis.

Resources