Last active
September 29, 2018 17:41
-
-
Save mndrix/572871177fa477e79ddb to your computer and use it in GitHub Desktop.
Prolog DCG utility predicates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% at_least//2 is like at_least//3 but ignores the specific matches found. | |
:- meta_predicate at_least(+,3,*,*). | |
at_least(N,Goal) --> | |
at_least(N,Goal,_). | |
% at_least(N,Goal,Matches) consumes at least N matches of Goal. | |
% after that, it consumes as much as possible. | |
:- meta_predicate at_least(+,3,?,*,*). | |
at_least(N0,Goal,[X|Xs]) --> | |
{ N0 > 0 }, | |
!, | |
call(Goal,X), | |
{ N is N0 - 1 }, | |
at_least(N,Goal,Xs). | |
at_least(0,Goal,Xs) --> | |
greedy(Goal,Xs). | |
% exactly(N,Goal) consumes exactly N matches of Goal. | |
:- meta_predicate exactly(+,3,*,*). | |
exactly(N,Goal) --> | |
exactly(N,Goal,_). | |
% exactly(N,Goal,Matches) consumes exactly N matches of Goal. | |
:- meta_predicate exactly(+,3,?,*,*). | |
exactly(0,Goal,[]) --> | |
\+ call(Goal,_). | |
exactly(N0,Goal,[X|Xs]) --> | |
{ N0 #> 0 }, | |
{ N #= N0 - 1 }, | |
call(Goal,X), | |
exactly(N,Goal,Xs). | |
% match as few Goal as possible | |
:- meta_predicate generous(3,-,*,*). | |
generous(_Goal,[]) --> | |
[]. | |
generous(Goal,[X|Xs]) --> | |
call(Goal,X), | |
generous(Goal,Xs). | |
:- meta_predicate greedy(3,*,*). | |
greedy(Goal) --> | |
greedy(Goal,_). | |
% match as many copies of Goal as possible | |
:- meta_predicate amalog_dcg:greedy(3,-,*,*). | |
greedy(Goal,[X|Xs]) --> | |
( call(Goal,X) -> [] ), | |
greedy(Goal,Xs). | |
greedy(_,[]) --> | |
[]. | |
%% list(ElemDCG, SeparatorDCG, Elems)// | |
% | |
% Describes a list in which the elements match ElemDCG and the | |
% separators match SeparatorDCG. Elems is the list of elements found. | |
% The set of patterns matched by ElemDCG and SeparatorDCG | |
% should be disjoint. Both DCG goals are called with one extra argument. | |
:- meta_predicate list(3,2,?,?,?). | |
list(ElemDCG, SepDCG, [Elem|Tail]) --> | |
call(ElemDCG, Elem), | |
( call(SepDCG), | |
!, | |
list(ElemDCG, SepDCG, Tail) | |
; "", | |
{ Tail = [] } | |
). | |
% followed_by(Goal) is true if Goal would match. Consumes nothing. | |
:- meta_predicate amalog_dcg:followed_by(//,*,*). | |
followed_by(Goal) --> | |
\+ \+ Goal. | |
% match the end of string | |
eos([],[]). | |
%% when_generating(:Goal)// | |
% | |
% Call Goal when DCG operates in generator mode. | |
:- meta_predicate when_generating(0,?,?). | |
when_generating(Goal) --> | |
( parsing -> []; { call(Goal) } ). | |
%% when_parsing(:Goal)// | |
% | |
% Call Goal when DCG operates in parsing mode. | |
:- meta_predicate when_parsing(0,?,?). | |
when_parsing(Goal) --> | |
( parsing -> { call(Goal) }; [] ). | |
%% parsing// is semidet. | |
% | |
% True if DCG is operating as a parser. Specifically, | |
% the DCG list is not a variable. | |
parsing(H,H) :- | |
nonvar(H). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment