Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using list in Prolog DCG

Tags:

prolog

dcg

I am trying to convert a Prolog predicate into DCG code. Even if I am familiar with grammar langage I have some troubles to understand how DCG works with lists and how I am supposed to use it.

Actually, this is my predicate :

cleanList([], []).
cleanList([H|L], [H|LL]) :-
    number(H),
    cleanList(L, LL),
    !.
cleanList([_|L], LL) :-
    cleanList(L, LL).

It is a simple predicate which removes non-numeric elements. I would like to have the same behaviour writes in DCG.

I tried something like that (which does not work obviously) :

cleanList([]) --> [].
cleanList([H]) --> {number(H)}.
cleanList([H|T]) --> [H|T], {number(H)}, cleanList(T).

Is it possible to explain me what is wrong or what is missing ?

Thank you !

like image 337
Naeoth Avatar asked Dec 11 '25 02:12

Naeoth


1 Answers

The purpose of DCG notation is exactly to hide, or better, make implicit, the tokens list. So, your code should look like

cleanList([]) --> [].
cleanList([H|T]) --> [H], {number(H)}, cleanList(T).
cleanList(L) --> [H], {\+number(H)}, cleanList(L).

that can be made more efficient:

cleanList([]) --> [].
cleanList([H|T]) --> [H], {number(H)}, !, cleanList(T).
cleanList(L) --> [_], cleanList(L).

A style note: Prologgers do prefers to avoid camels :)

clean_list([]) --> [].
etc...

Also, I would prefer more compact code:

clean_list([]) --> [].
clean_list(R) --> [H], {number(H) -> R = [H|T] ; R = T}, clean_list(T).
like image 91
CapelliC Avatar answered Dec 13 '25 23:12

CapelliC