2
votes

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.

1
In SWI-Prolog, set the Prolog flag double_quotes to chars (recommended) or codes to turn everything within double quotes into a list of characters or codes. This is how it should have been in the first place, and what also other Prolog systems do. You can also use the command line option --traditional to get standard-conforming behaviour in this regard.mat
@mat Great! this was the kind of answer I was looking for. It works when I start up swipl with --traditional but it doesn't work with all the bash scripts that are being used, is there any way to set it system-wide?Richard Deurwaarder
You can add a Bash alias, for example: alias swipl='/usr/local/bin/swipl --traditional', or put :- set_prolog_flag(double_quotes, chars). in your ~/.swiplrc. Note this all leads to extremely fun situations when your instructor uses a different way to invoke SWI-Prolog. It's almost as if there should be a standard for Prolog!mat
The bash alias doesn't work because the the bash scripts use the absolute path. But I got one step further adding set_prolog_flag to my .swiplrc. Now I get ERROR: </2: Arithmetic: `'I'/0' is not a function Could that be caused by a similar prolog flag?Richard Deurwaarder
Probably you have some code that relies on double_quotes being set to codes, you can try that. Note that ideally, library code should be written to work with both chars and codes! Historically, chars was the first and preferable option (i.e., double quotes were treated as a list of characters); later, this was changed to codes, and I think the long-term best option is to come back again to chars at last. So, short term, set double_quotes to codes in order to work around the SWI 7 problems, and make your future code safe to work with chars!mat

1 Answers

3
votes

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:

  1. invoke SWI-Prolog with the --traditional flag
  2. add :- initialization(set_prolog_flag(double_quotes, codes)). to your source file.
  3. 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.