To reproduce, please clone the repository
https://github.com/triska/the-power-of-prolog/
and start the server with:
$ scryer-prolog -g "server(6012)" server.pl
Then direct your browser to: http://localhost:6012/prolog/clpfd
The server emits:
waiting for connections... handling client '127.0.0.1:59647'... request is for "prolog/clpfd" sending 'prolog/clpz.html' etc.
This works completely as expected.
However, when I change the order of clauses in the definition of path_file/2 to read:
path_file("prolog", "prolog/prolog.html").
path_file("prolog/clpfd", "prolog/clpz.html").
path_file(Path, HTML) :- append(Path, ".html", HTML).
path_file(Path, File) :-
path_segments(Path, Segments),
append(_, [Last,[]], Segments),
phrase(format_("~s~s.html", [Path,Last]), File).
path_file(Path, Path).
i.e., I move the previously fourth clause to become the second clause, and then direct my browser to http://localhost:6012/prolog/clpfd, then I get:
waiting for connections... handling client '127.0.0.1:59616'... request is for "prolog/clpfd" redirecting to: https://www.metalevel.at/prolog/clpfd waiting for connections...
This seems to indicate that the second clause is now ignored, even though I expect it to be applicable for the requested path, "prolog/clpfd", and I expect the server to respond with the contents of prolog/clpz.html exactly as above.
The issue seems to be in Path. With this test:
$ echo "prolog/clpfd" > path.txt
$ cat test.pl
:- use_module(library(debug)).
:- use_module(library(dcgs)).
:- use_module(library(format)).
:- use_module(library(pio)).
seq([]) --> [].
seq([S|Ss]) --> [S], seq(Ss).
path_file("prolog", "prolog/prolog.html").
path_file("prolog/clpfd", "prolog/clpz.html").
path_file(A, B) :- format("a: ~q ~q\n", [A, B]).
$ scryer-prolog test.pl
?- phrase_from_file((seq(Path), "\n"), 'path.txt'), Path = "prolog/clpfd", path_file(Path, HTML).
a: "prolog/clpfd" A
Path = "prolog/clpfd"
; false.
?- *phrase_from_file((seq(Path), "\n"), 'path.txt'), Path = "prolog/clpfd", path_file(Path, HTML).
Path = "prolog/clpfd", HTML = "prolog/clpz.html"
; a: "prolog/clpfd" A
Path = "prolog/clpfd"
; false.
?-
This could be a partial string issue or phrase/phrase_from_file issue. More investigation is required.
A brilliant test case, thank you a lot!
To avoid introducing unintended solutions, I often use false/0 when a clause is used only for output:
path_file(A, B) :- format("a: ~q ~q\n", [A, B]), false.
Yielding:
?- phrase_from_file((seq(Path), "\n"), 'path.txt'), Path = "prolog/clpfd", path_file(Path, HTML). a: "prolog/clpfd" A false.
and
?- *phrase_from_file((seq(Path), "\n"), 'path.txt'), Path = "prolog/clpfd", path_file(Path, HTML). Path = "prolog/clpfd", HTML = "prolog/clpz.html" ; a: "prolog/clpfd" A false.
This makes the difference immediately clear: One query succeeds, and the other fails without a single solution.
With path.txt as above, the following program shows the problem very clearly:
:- use_module(library(debug)).
:- use_module(library(dcgs)).
:- use_module(library(pio)).
seq([]) --> [].
seq([S|Ss]) --> [S], seq(Ss).
path_file("prolog", "prolog/prolog.html").
path_file("prolog/clpfd", "prolog/clpz.html").
We have:
?- Path = "prolog/clpfd", phrase_from_file((seq(Path), "\n"), 'path.txt'), path_file(Path, HTML). Path = "prolog/clpfd", HTML = "prolog/clpz.html".
But generalizing the query fails:
?- *Path = "prolog/clpfd", phrase_from_file((seq(Path), "\n"), 'path.txt'), path_file(Path, HTML). false.
Here is another example of this phenomenon that arises before and also after the most recent commit:
test("a").
test("b").
I get, as expected:
?- test(Ls), Ls = [a|_]. Ls = "a" ; false.
However, exchanging the order of goals yields:
?- Ls = [a|_], test(Ls). false.
This works nicely now, thank you a lot!
Are there any other cases like this? If not, I can close #642 too, however, I think adding a safeguard may still be a good idea!
Are there any other cases like this? If not, I can close #642 too, however, I think adding a safeguard may still be a good idea!
Not that I've found. Perhaps we should leave it open for a while in case we discover further issues?
Perfect, I will leave it open!
Issues like these are the worst problem: In a complex computation, nobody can tell whether there are solutions that ought to be reported but were not found by the system (for example, due to a problem with indexing). It is much preferable to crash instead of incorrectly failing silently, because then we at least get a chance to debug and correct the issue. Otherwise, such mistakes may go unnoticed, silently yielding incorrect results.
Most helpful comment
The issue seems to be in
Path. With this test:This could be a partial string issue or
phrase/phrase_from_fileissue. More investigation is required.