%
%   Some DCG tools
%
%

file_search_path(semwalker, '/home/sandro/semwalker').
:- ensure_loaded(semwalker(qtest)).

%%
%%  zero_or_more(Goal, Li, Lo)
%%
%%  Match "Goal" in a grammar from Li to Lo, matching
%%  zero or more times in sequence. 
%%
zero_or_more(Goal, Li, Lo) :-
	ground(Li),
	apply(Goal, [Li, Lx]),
	ground(Lx),
	(   Lx == Lo
	->  true
	;   zero_or_more(Goal, Lx, Lo)
	).
zero_or_more(_Goal, Li, Lo) :-
	ground(Li),
	Li == Lo.

is_x --> [x].
qtest :- zero_or_more(is_x, [], []).
qtest :- zero_or_more(is_x, [x], []).
qtest :- zero_or_more(is_x, [x,x,x,x,x,x,x,x], []).
qtest :- \+ zero_or_more(is_x, [x,x,x,yyyyyy,x,x], []).
	

%%
%%  zero_or_more(Goal, CollectedOutput, Li, Lo)
%%
%%  Goal is called as Goal(P,Lx,Ly)
%%
%%
%%  Like zero_or_more/3 but Goal is called with a parameter and
%%  CollectedOutput is a list of each parameter Goal was called with.
%%  It will have one element for each time the Goal was used.
%%
%%
zero_or_more(Goal, [P|Ps], Li, Lo) :-
	apply(Goal, [P, Li, Lx]),
	(   Lx == Lo     %% not unification; don't bind Lo
	->  Ps = []
	;   zero_or_more(Goal, Ps, Lx, Lo)
	).
zero_or_more(_Goal, [], Li, Li).

qtest :-
	zero_or_more(zomtest, C, [], []),
	C = [].
qtest :-
	zero_or_more(zomtest, C, [x,x,x], []),
	C = [1,1,1].
qtest :-
	zero_or_more(zomtest, C, [x,x,x,x], []),
	C = [1,1,1,1].
qtest :-
	\+ zero_or_more(zomtest, _, [x,x,y,x], []).
qtest :-
	Rest = [y, x],
	zero_or_more(zomtest, _, [x,x,y,x], Rest).
qtest :-
	% this test fails if "=" is used instead of "==".
	zero_or_more(zomtest, _, [x,x,y,x], Rest),
	Rest = [y, x].



zomtest(R) -->
	[x],
	{ R = 1 }.
	

optional(_, Li, Li).
optional(Text, Li, Lo) :-
	(   Text = [_|_]
	->  append(Text, Lo, Li)
	;   call(Text, Li, Lo)
	).






optional_whitespace -->
          ""
        ; whitespace_character, optional_whitespace.

whitespace -->
          whitespace_character
        ; whitespace_character, optional_whitespace.

whitespace_character -->
	[D], { number(D), code_type(D, space) }.

qtest(optional_whitespace("", "")).
qtest(optional_whitespace(" ", "")).
qtest(optional_whitespace("\n", "")).
qtest(optional_whitespace("\t\t\t  \n\n  \t ", "")).
