sten
sten

Reputation: 7486

DCG: hidden argument across all Rules?

.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 ?

Upvotes: -1

Views: 131

Answers (3)

CapelliC
CapelliC

Reputation: 60034

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.

Upvotes: 2

Paulo Moura
Paulo Moura

Reputation: 18683

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

Upvotes: 2

David Tonhofer
David Tonhofer

Reputation: 15338

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)...

Upvotes: 2

Related Questions