trealla-prolog / trealla

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

DCG interesting example #71

Open mingodad opened 2 years ago

mingodad commented 2 years ago

Looking through github to find an interesting example for DCG's to test with trealla I found this https://github.com/litwr2/dcg-based-parser but id doesn't work out of the box with trealla.

The docs are here https://litwr2.github.io/dcg-based-parser.html . Could this be adapted to trealla and added to samples ?

infradig commented 2 years ago

There's some non-standard stuff in there, it would be of dubious value to support them. Not even SWI Prolog has them... unget_char/1 for instance.

On Tue, Nov 1, 2022 at 9:13 PM Domingo Alvarez Duarte < @.***> wrote:

Looking through github to find an interesting example for DCG's to test with trealla I found this https://github.com/litwr2/dcg-based-parser but id doesn't work out of the box with trealla.

The docs are here https://litwr2.github.io/dcg-based-parser.html . Could this be adapted to trealla and added to samples ?

— Reply to this email directly, view it on GitHub https://github.com/trealla-prolog/trealla/issues/71, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFNKSETMM4645C4V6RVF6IDWGD3PFANCNFSM6AAAAAART6T5ME . You are receiving this because you are subscribed to this thread.Message ID: @.***>

mingodad commented 2 years ago

I'm asking this here because it's short and it's a topic of my practical interest, but my actual knowledge of Prolog isn't that great at the moment. It doesn't need to be exactly like that, but the overall functionality yes.

mingodad commented 2 years ago

Trealla also has several non standard stuff.

guregu commented 2 years ago

The JSON library included in Trealla (borrowed from Scryer) is a nice modern DCG: https://github.com/trealla-prolog/trealla/blob/main/library/json.pl although it can get rather slow.

This Markdown library by @aarroyoc supports Trealla: https://github.com/aarroyoc/marquete

guregu commented 2 years ago

I don't think it's Trealla's fault the JSON library is slow, btw. Scryer has the same problem (https://github.com/mthom/scryer-prolog/issues/1566). The code is very nice though.

mingodad commented 2 years ago

Thank you @guregu for the links ! Have you done any profiling to see where the problem is (slow) ?

guregu commented 2 years ago

For the WebAssembly ports, I needed fast JSON so I attempted to fix it. Unfortunately, it's beyond my ability at the moment. I would imagine that an application of a cut or two in the right place could help it, but it might be an issue with it using dif/2 instead, honestly no idea. The issue on Scryer's repo has some measurements. We could maybe try to borrow SWI's JSON DCG instead but I haven't looked at it closely.

I ended up making a hacky module that abuses Trealla's term reading/writing to do JSON stuff, taking advantage of the fact that JSON is a valid Prolog term. It does the job and it's very fast but it's not pretty :-)

infradig commented 2 years ago

Trealla and Scryer use the same reference implementation of DCGs in Prolog. Others probably use a native version, which even if transcribed, are probably faster.

On Tue, Nov 1, 2022 at 10:37 PM guregu @.***> wrote:

For the WebAssembly ports, I needed fast JSON so I attempted to fix it. Unfortunately, it's beyond my ability at the moment. I would imagine that an application of a cut or two in the right place could help it, but it might be an issue with it using dif/2 instead, honestly no idea. The issue on Scryer's repo has some measurements. We could maybe try to borrow SWI's JSON DCG instead but I haven't looked at it closely.

I ended up making a hacky module https://github.com/guregu/trealla/blob/main/library/pseudojson.pl that abuses Trealla's term reading/writing to do JSON stuff, taking advantage of the fact that JSON is a valid Prolog term. It does the job and it's very fast but it's not pretty :-)

— Reply to this email directly, view it on GitHub https://github.com/trealla-prolog/trealla/issues/71#issuecomment-1298449334, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFNKSEXGDAUNDBOYQRPDVX3WGEFKNANCNFSM6AAAAAART6T5ME . You are receiving this because you commented.Message ID: @.***>

pmoura commented 2 years ago

There's some non-standard stuff in there, it would be of dubious value to support them. Not even SWI Prolog has them... unget_char/1 for instance.

Possibly calls to get_char/1 + unget_char/1 can be replaced with calls to peek_char/2.

Another issue is the non-standard syntax for the dynamic directive. For example (in file hoc3x.pro):

:- dynamic(names/2, ids/1, eoi/0).

This should be either:

:- dynamic((names/2, ids/1, eoi/0)).

or:

:- dynamic([names/2, ids/1, eoi/0]).

There's also the use of a non-standard Prolog flag: syntax_error.

pmoura commented 2 years ago

The JSON library included in Trealla (borrowed from Scryer) is a nice modern DCG: https://github.com/trealla-prolog/trealla/blob/main/library/json.pl although it can get rather slow.

There's also in alternative Logtalk's json library. It should be faster.

mingodad commented 2 years ago

Thank you @pmoura for discovering https://github.com/trealla-prolog/trealla/issues/73 when trying to test https://github.com/litwr2/dcg-based-parser !

Another interesting project that I'm looking now is https://github.com/souffle-lang/souffle and it has a nice way to declare relations and read input data in a more secure less verbose way (see here https://souffle-lang.github.io/simple).

.decl edge(x:number, y:number)
.input edge

.decl path(x:number, y:number)
.output path

path(x, y) :- edge(x, y).
path(x, y) :- path(x, z), edge(z, y).

edge.facts:

1   2
2   3

Could trealla also support this ?

pmoura commented 2 years ago

Without trying to address parsing of the declarations, assuming edge.facts is a TSV file, using Logtalk's csv library with Trealla:

$ tplgt
...

?- {csv(loader)}.
...
   true.
?- assertz(edge(_,_)), retractall(edge(_,_)).
   true.
?- csv(keep, tab, true)::read_file('edge.facts', user, edge/2).
   true
;  ... .
?- edge(A, B).
   A = 1, B = 2
;  A = 2, B = 3.
?- 
mingodad commented 2 years ago

That's the idea but as builtin and a lot less verbose !

mingodad commented 2 years ago

And also with a cheery on top, naming the arguments and using types.

pmoura commented 2 years ago

That's the idea but as builtin and a lot less verbose !

This functionality could be best added as a library, not as a built-in feature.

infradig commented 2 years ago

Not sure what you're asking for here. You can easily parse a CSV or TSV...

$ tpl ?- split("1\t2",'\t',L,R). L = "1", R = "2". ?- split_string("1\t2",'\t',' ',L). L = ["1","2"].

?- help(split/4). split/4: split(+string,+string,?left,?right) true. ?- help(split_string/4). split_string/4: split_string(+string,+sep,+pad,-list) true.

Where split_string/4 is compatible with SWI Prolog.

It doesn't nicely convert to numbers.

I would second Paulo in writing such applications in Logtalk, you gain greatly in portability. I cannot imaging adding extensions like this Souffle to Trealla.