-1

.in DCG is there a way to have hidden argument i.e. argument is passed in the top rule , but I dont mention it in the rest of the rules , but i still have access to it.

 S(Ctx,A,B) --> ...
 R1(A) --> ....
 R2(A) --> ..R5(A), { write(Ctx) }
 R3(A) --> ..add2ctx(abc,Ctx), remove4ctx(bcd,Ctx)..

the same way that DCG is syntax-sugar over difference lists I just want to skip declaring a variable it in the rules head and when I call another rule ?

sten
  • 7,028
  • 9
  • 41
  • 63

3 Answers3

2

No there is not. Whenever data has to be passed to a clause, it must be done so explicitly. You cannot define a piece of "context information" implicitly visible to all DCG roles.

But there is this note in the SWI-Prolog manual:

phrase/3

A portable solution for threading state through a DCG can be implemented by wrapping the state in a list and use the DCG semicontext facility. Subsequently, the following predicates may be used to access and modify > the state.

state(S), [S] --> [S].
state(S0, S), [S] --> [S0].

So the idea here is that you have term that describes a "current state" that you hot-potatoe from one DCG rule to the next by

  1. Getting it from the input list
  2. Transforming it from a state S0 to a state S
  3. Then putting it back onto the list so that it is available for the next rule.

For example

state(S), [S] --> [S].

does not modify the state and just pushes it back on the list.

But

state(S0, S), [S] --> [S0].

grabs the state S0, maps it to S and put it back onto the list. That should be the idea I think. But in that example, there should probably be something more in the body, namely a call to some p(S,S0)...

David Tonhofer
  • 14,559
  • 5
  • 55
  • 51
  • One can of course always assert some clause (and evidently, some fact) in the Prolog database using [`assertz/1`](https://eu.swi-prolog.org/pldoc/doc_for?object=assertz/1), but that sounds ... not right. – David Tonhofer Jan 15 '21 at 20:46
  • thanks, also found this : https://www.metalevel.at/prolog/dcg, but finding hard to grasp it .. – sten Jan 15 '21 at 22:18
  • so state() is a shortcut to use to pass the state info, rather than using semi-ctx notation – sten Jan 15 '21 at 22:22
2

Is not completely clear what you want to accomplish. The implicit arguments of a grammar rule are used for threading state as described e.g. in David's answer. It's however also possible to share implicit logical variables with all grammar rules (but note that these cannot be used for threading state). This can be easily accomplished by encapsulating your grammar rules in a Logtalk parametric object. For example:

:- object(grammar(_Ctx_)).

    :- public(test/2).
    test(L, Z) :-
        phrase((a(Z); b(Z)), L).

    a(Y) --> [aa, X], {atom_concat(X, _Ctx_, Y)}.
    
    b(Y) --> [bb, X], {atom_concat(_Ctx_, X, Y)}.

:- end_object.

Some sample queries:

?- {grammar}.
% [ /Users/pmoura/grammar.lgt loaded ]
% (0 warnings)
true.

?- grammar(foo)::test([aa,cc], Z).
Z = ccfoo .

?- grammar(foo)::test([bb,cc], Z).
Z = foocc.

Would this work in your case? You can run this example with all Logtalk supported Prolog systems. You can also read more about parametric objects and parameter variables at https://logtalk.org/manuals/userman/objects.html#parametric-objects

Paulo Moura
  • 18,373
  • 3
  • 23
  • 33
  • sort of yes&no, I want to be able to add to context and remove from context. Also one thing i did not mention to complicate thinngs I will have multiple start rules which will accept Ctx arg i.e. like "multiple grammars" in a single grammar i.e. i will be using DCG to parse different text templates and invoke action on match, something like MATCH-TEXT-PATTERN => ACTION. F.e. "add $V"; "add element $V"; "add item $V" => { lst += $V }. Ctx is used as selector if there are similar Templates let say SET vs LIST ctx – sten Jan 15 '21 at 22:14
  • 1
    @sten Object parameters **are** logical variables. But there's a library for logical assignment of Prolog terms (https://logtalk.org/manuals/libraries/assignvars.html) that may provide a solution. An example using this library is https://github.com/LogtalkDotOrg/logtalk3/tree/master/examples/assign_parameters Some Prolog systems provide *attributed variables*. It may be possible to represent the context using attributes assigned to object parameters. But note that such a solution will not be portable (related example: https://github.com/LogtalkDotOrg/logtalk3/tree/master/examples/attvars). – Paulo Moura Jan 15 '21 at 22:31
2

In SWI-Prolog there is a ready-to-use and battle-proven pack, that builds on the DCG concept. It does require a bit of learning, but don't fear, it's well supported.

CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • EDCGs are also available as a Logtalk library and thus usable in most Prolog systems. It's also a more robust version that the one in that pack. – Paulo Moura Jan 16 '21 at 09:46