The following Prolog prints done
for goals test1
and test2
, but not test3
. My understanding is that match_test2
and match_test3
in this code should be equivalent. How do I create a DCG rule via an assertion?
setup(['t','e','s','t']).
match_test1 --> ['t','e','s','t'].
test1 :-
setup(C),
phrase(match_test1,C),
write("done").
test2 :-
setup(C),
assert(match_test2(['t','e','s','t'],[])),
phrase(match_test2,C),
write("done").
test3 :-
setup(C),
assert(match_test3 --> ['t','e','s','t']),
phrase(match_test3,C),
write("done").
Using SWI-Prolog version 7.2.3 for x86_64-darwin14.3.0, running as swipl -l bug.pl -t test1
(or test2
, test3
)
Use expand_term/2
to translate the DCG to a regular clause first:
?- expand_term(match_test1 --> [t,e,s,t], Clause). Clause = (match_test1([t, e, s, t|_1498], _1498):-true).
Then use assertz/1
as usual on Clause
, i.e., assertz(Clause)
.
Note that you can write down the atoms directly, i.e., instead of 'e'
, simply write e
.
In addition, consider setting double_quotes
to chars
by adding the directive:
:- set_prolog_flag(double_quotes, chars).
Now you can write, very conveniently:
?- T = "test". T = [t, e, s, t].
This syntax is very nice and makes DCGs a lot easier to debug and work with.