Questions tagged [dcg]

DCGs (Definite Clause Grammars) are a compact way to describe lists in Prolog.

DCGs (Definite Clause Grammars) are a compact way to describe lists in Prolog.

DCGs are usually associated with , but similar languages such as also include DCGs. They are called definite clause grammars because they represent a grammar as a set of definite clauses in first-order logic.

Some interesting contributions are available as SWI-Prolog packs, like

I like to think of DCGs as Attribute Grammars made practical.


References:

DCGs provide a threading state abstraction: don't break it


SWI-Prolog and double quotes

Many examples of DCGs on SO, in blogs and papers use the traditional and ISO standard conforming definition for double quotes. If you take such code and use it directly with SWI-Prolog it will sometimes fail because SWI uses by default double quoted syntax for its string type.

?- phrase("abc","abc").         % succeeds in other Prologs
ERROR: Type error: `list' expected, found `"abc"' (a string)

To make the examples work in SWI-Prolog set Prolog flags in .swiplrc or issue them directly on the top level.

:- set_prolog_flag(double_quotes, chars).   % or codes
:- set_prolog_flag(back_quotes, string).    % ISO conforming extension

Otherwise, to ensure the SWI-specific setting, proceed as in the following example.

:- module(course,
      [ courses//1,
        parse_courses/2
      ]).

:- [library(dcg/basics)].

:- set_prolog_flag(double_quotes, string).   % SWI's default setting
:- set_prolog_flag(back_quotes, codes).      % SWI's default setting

courses([Course|Courses]) -->
    course(Course),
    courses(Courses), !.
courses([]) --> [].

course(course(Course,Students)) -->
    string_without("\n", Course_codes),
    { string_codes(Course,Course_codes ) },
    "\n",
    students(Students),
    (
        empty_line
    ;
        []
    ).

students([Student|Students]) -->
    student(Student),
    students(Students).
students([]) --> [].

student(Student) -->
    spaces_or_tabs_plus,
    (
        (
            string_without("\n",Student_codes),
            { string_codes(Student,Student_codes) },
            "\n"
        )
    ;
        remainder(Student_codes),
        { string_codes(Student,Student_codes) }
    ).

spaces_or_tabs_plus -->
    space_or_tab,
    spaces_or_tabs_star.

spaces_or_tabs_star -->
    space_or_tab,
    spaces_or_tabs_star.
spaces_or_tabs_star --> [].

space_or_tab -->
    (
        "\s"
    |
        "\t"
    ).

empty_line --> "\n".

parse_courses(Codes,Courses) :-
    DCG = courses(Courses),
    phrase(DCG,Codes,Rest),
    assertion( Rest == [] ).

:- begin_tests(course).

:- set_prolog_flag(double_quotes, string).
:- set_prolog_flag(back_quotes, codes).

test(001) :-
    Input = "\c
        MATH2221\n\c
            \t201000001\n\c
            \t201000002\n\c
            \n\c
        MATH2251\n\c
            \t201000002\n\c
            \t201000003\n\c
            \n\c
        COMP2231\n\c
            \t201000003\n\c
            \t201000001\c
        ",
    string_codes(Input,Codes),
    parse_courses(Codes,Courses),

    assertion( Courses ==
        [
            course("MATH2221",["201000001","201000002"]),
            course("MATH2251",["201000002","201000003"]),
            course("COMP2231",["201000003","201000001"])
        ]
    ).

:- end_tests(course).

482 questions
5
votes
1 answer

parsing and generating multi-level list structures with DCG

Suppose I call an "a-list" a list of zero or more "a"s: % as = [a,a,a] as --> []. as --> [a], as. Suppose I want to represent a "b-list”, a list of zero or more a-lists: % bs := [ as, as ] % bs = [ [a,a,a], [a] ] bs --> []. bs --> [A], {…
5
votes
2 answers

How to generate distinct solutions in Prolog for '8 out of 10 cats does countdown' numbers game solver?

I wrote a Prolog program to find all solutions to any '8 out of 10 cats does countdown' number sequence. I am happy with the result. However, the solutions are not unique. I tried distincts() and reduced() from the "solution sequences" library. They…
Mousali
  • 61
  • 1
  • 5
5
votes
1 answer

Custom DCG Operators

Suppose I want to write a custom operator for composing DCG rules in a way that would otherwise be repetitive. For example, suppose I had I a DCG, ws such that: ws --> []. ws --> " ", ws. to match zero or more spaces. Obviously, if I want optional…
junius
  • 570
  • 3
  • 14
5
votes
4 answers

Prolog as a DSL to generate perl code?

Does anyone know of any examples of code written in prolog to implement a DSL to generate perl code?
5
votes
1 answer

Optional or Repeated Items in Prolog DCG

So I'm writing a simple parser for Pascal in SWI-Prolog using Definite Clause Grammars. I don't understand how to implement repeating (2 or more) or optionally repeating (1 or more) predicates. For example, in EBNF, for Pascal's "program"…
Marcus Hallett
  • 105
  • 1
  • 7
5
votes
1 answer

Prolog - formulas in propositional logic

I am trying to make a predicate in order to validate if a given input represents a formula. I am allowed to use only to propositional atoms like p, q, r, s, t, etc. The formulas which I have to test are the following: neg(X) - represents the…
Simon
  • 4,999
  • 21
  • 69
  • 97
5
votes
2 answers

Prolog, reconstruct BST trees from inorder list

We well know inorder implementation for BST tree. inorder(nil, []). inorder(t(Root, L, R), List) :- inorder(L, ListLeft), inorder(R, ListRight), append(ListLeft, [Root|ListRight], List). However, is it possible to do it for list ? I…
user6023611
5
votes
5 answers

prolog - sublist of list - alternative approach

I implemented function to get sublist of list, for example: sublist([1,2,4], [1,2,3,4,5,1,2,4,6]). true sublist([1,2,4], [1,2,3,4,5,1,2,6]). false look at my solution: my_equals([], _). my_equals([H1|T1], [H1|T2]) :- my_equals(T1,…
user6023611
5
votes
1 answer

How do Prolog translates DCG rules into definite clauses?

I'm studying Definite Clause Grammar, but I have some problem to understand how Prolog translates DCG rules into definite clauses. For example, here's a little grammar written as DCG: s --> np, vp. np --> det, n. vp --> v, np. vp --> v. det -->…
s.dallapalma
  • 1,225
  • 1
  • 12
  • 35
5
votes
2 answers

When to use phrase in Prolog?

I'm trying to learn more about DCGs in Prolog and while reading through different sources, I noticed that in some cases phrase wasn't being used ? From the Learn Prolog Now website, it presents this example: s --> np,vp. np --> det,n. vp -->…
5
votes
2 answers

writing context free grammar in prolog

let's say I had the following context free grammar. S -> A A -> mAn A -> o How would this look in prolog? This is what I tried but it doesn't work. The second line seems to be the issue. S(Z) :- A(Z). A(Z) :- append([m],X,Z2), A(X),…
snctmpst
  • 135
  • 1
  • 5
5
votes
1 answer

What is the general pattern for creating a dcg for file input?

I always seem to struggle to write DCG's to parse input files. But it seems it should be simple? Are there any tips or tricks to think about this problem? For a concrete example, lets say I want to parse a fasta file.…
user27815
  • 4,767
  • 14
  • 28
5
votes
3 answers

Learn Prolog Now! DCG Practice Example

I have been progressing through Learn Prolog Now! as self-study and am now learning about Definite Clause Grammars. I am having some difficulty with one of the Practical Session's tasks. The task reads: The formal language anb2mc2mdn consists of…
Timothy
  • 4,630
  • 8
  • 40
  • 68
5
votes
3 answers

Structure (Difference Lists) Prolog

This question refers to the material in chapter 3 of the book: Programming in Prolog, Clocksin and Mellish, Ed 5 In page 72 of this book, a program using difference list is displayed: partsOf(X,P):- partsacc(X,P,Hole) ,…
Karl 17302
  • 57
  • 6
5
votes
1 answer

How to do a Tree Transfer in prolog for MT

I need to find a way to Transfer a parse tree in to another with different order. It is for machine translation project with two languages with SVO and SOV architecture. t1 = s(np(n(he)), vp( v(went), np(n(home)))) and I want it to be t2 =…
Mathee
  • 691
  • 7
  • 16