trealla-prolog / trealla

A compact, efficient Prolog interpreter written in plain-old C.
MIT License
268 stars 13 forks source link

DCG restrictions on the left-hand side #574

Closed Jean-Luc-Picard-2021 closed 2 months ago

Jean-Luc-Picard-2021 commented 2 months ago

I wonder whether it makes sense to accept this:

$ ./tpl -v
Trealla Prolog (c) Infradig 2020-2024, v2.55.10

$ ./tpl
?- [user].
p;q --> r.
   true.

?- listing((;)/4).
;(p,q,A,B) :-
   r(A,B).
   true.

You will not be able to call (;)/4 via phrase/[2,3] since it translates DCG (;)/2. So SWI-Prolog forbids it:

?- [user].
|: p;q --> r.

ERROR: user://1:29:
ERROR:    No permission to define dcg_nonterminal `p;q'

See also:

https://eclipseclp.org/wiki/Prolog/DCG

infradig commented 2 months ago

The dcg.pl in Trealla is like the one in Scryer Prolog, a copy of UWN's reference implementation. So best take it up with him.

Jean-Luc-Picard-2021 commented 2 months ago

Yeah Scryer Prolog has the same tolerance. It also allows a nonsensical DCG clause (p;q --> r). But

Scryer Prolog has an interesting feature. It doesn't allow this one, preventing the end-user from accidentially

fiddling with (-->)/2:

/* Scryer Prolog */
?- a-->b.
   error(existence_error(procedure,(-->)/2),(-->)/2).
?- assertz((a-->b)).
   error(permission_error(modify,static_procedure,(-->)/2),assertz/1).
?- a-->b.
   error(existence_error(procedure,(-->)/2),(-->)/2).

In Trealla Prolog it is not bared:

/* Trealla Prolog */
?- a-->b.
   throw(error(existence_error(procedure,(-->)/2),(-->)/2)).
?- assertz((a-->b)).
   true.
?- a-->b.
   true.
infradig commented 2 months ago

I get this...

$ scryer-prolog
?- a-->b.
   error(existence_error(procedure,(-->)/2),(-->)/2).
?- assertz((a-->b)).
   true.
?- a-->b.
   true.
?- 
infradig commented 2 months ago

Oh, i see, after a use_module(library(dcgs))

Jean-Luc-Picard-2021 commented 2 months ago

I think use_module(library(dcgs)) is not necessary. Its loaded during bootstrapping of Scryer Prolog? Or I have it in my .scryerrc file. Would need to double

check. They have this in their library(dcgs):

(_-->_) :- throw(error(existence_error(procedure,(-->)/2),(-->)/2)).

I had such stuff in formerly Jekejeke Prolog as well. But I have a special existence error type especially for this use case of blocking a predicate. So now Dogelog

Player has since today:

% +Phrase --> +Phrase
(_ --> _) :-
   throw(error(existence_error(body,(-->)/2),_)).

The meta predicate declaration you see in library(dcgs), I also had them in formerly Jekejeke Prolog. But I don't have them anymore in Dogelog Player, because this

new Prolog system is simpler, and doesn't provide meta predicate declarations.