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


Note: When using DCGs with SWI-Prolog be aware of The string type and its double quoted syntax

In other words many examples of DCGs here, in blogs and papers use the traditional Prolog definition for double quotes. If you take such code and use it with SWI-Prolog it will sometimes fail.

To avoid this problem there are Prolog flags for changing how double quotes and back quotes are defined.

Example of Prolog DCG that sets Prolog flags.

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

:- [library(dcg/basics)].

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

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).

469 questions
7
votes
2 answers

What does the operator `-->` in Prolog do?

What does the --> operator do in Prolog and what is the difference between it and :-? I'm using SWI Prolog.
Joel Lindholm
  • 71
  • 1
  • 3
7
votes
4 answers

Check if string is substring in Prolog

Is there a way to check if a string is a substring of another string in Prolog? I tried converting the string to a list of chars and subsequently checking if the first set is a subset of the second that that doesn't seem to be restrictive enough.…
MaVe
  • 1,445
  • 4
  • 20
  • 28
7
votes
1 answer

Parsing with DCGs in Scheme (without Prolog)?

Lots of Prolog-in-Scheme implementations are out there. E.g. Kanren, Schelog. Apparently in "Paradigms of AI Programming" Norvig implements Prolog-to-Lisp compiler in Lisp in order to use Definite Clause Grammars. But is there a simpler cleaner way?…
z5h
  • 21,947
  • 8
  • 64
  • 119
7
votes
3 answers

Parsing inflected non-word-order languages (e.g. Latin)

Taking an example from the Introduction to Latin Wikiversity, consider the sentence: the sailor gives the girl money We can handle this in Prolog with a DCG fairly elegantly with this pile of rules: sentence(s(NP, VP)) --> noun_phrase(NP),…
Daniel Lyons
  • 21,545
  • 2
  • 48
  • 73
7
votes
3 answers

Extension to CFG, what is it?

Consider the following extension to context-free grammars that permits rules to have in the left-hand side, one (or more) terminal on the right side of the non-terminal. That is, rules of the form: A b -> ... The right-hand side may be anything,…
false
  • 10,182
  • 12
  • 93
  • 182
7
votes
3 answers

Removing left recursion in DCG - Prolog

I've got a small problem with left recursion in this grammar. I'm trying to write it in Prolog, but I don't know how to remove left recursion. -> ->
Finley Osbert
  • 113
  • 2
  • 8
6
votes
5 answers

Prolog - Palindrome Functor

I am trying to write a predicate palindrome/1 in Prolog that is true if and only if its list input consists of a palindromic list. for example: ?- palindrome([1,2,3,4,5,4,3,2,1]). is true. Any ideas or solutions?
Amjad
  • 1,566
  • 5
  • 18
  • 40
6
votes
3 answers

prolog Searching the Lists

I am trying to compare the lists. Given function(List1,List2) and List1 has length N and List 2 has length M and N>M. I want to check if any permutation of List2 happens to be the first M characters of…
forreal
  • 63
  • 3
6
votes
4 answers

Should text-processing DCGs be written to handle codes or chars? Or both?

In Prolog, there are traditionally two ways of representing a sequence of characters: As a list of chars, which are atoms of length 1. As a list of codes, which are just integers. The integers are to be interpreted as codepoints, but the convention…
David Tonhofer
  • 12,954
  • 4
  • 44
  • 46
6
votes
2 answers

Using a prolog DCG to find & replace - code review

I came up w/ the following code to replace all occurences of Find w/ Replace in Request & put the answer in Result. This is using a DCG, so they are all lists of character codes. The predicate that client code would use is…
Ashley
  • 833
  • 1
  • 5
  • 15
6
votes
1 answer

How to read a csv file into a list of lists in SWI prolog where the inner list represents each line of the CSV?

I have a CSV file that look something like below: i.e. not in Prolog format james,facebook,intel,samsung rebecca,intel,samsung,facebook Ian,samsung,facebook,intel I am trying to write a Prolog predicate that reads the file and returns a list that…
6
votes
4 answers

Concatting a list of strings in Prolog

I'm writing a Lisp to C translator and I have a problem with handling strings. This is a code that transforms an unary Lisp function to a C equivalent: define(F) --> fun_unary(F), !. fun_unary(F) --> "(define (", label(Fun), spaces, label(Arg1),…
Igor
  • 2,475
  • 5
  • 29
  • 36
6
votes
4 answers

Question - formal language in prolog

I am trying to build a DCG which recognizes all lists which match this form : a^n b^2m c^2m d^n. I have written up the following rules: s --> []. s --> ad. ad --> a, ad, d. ad --> bc. bc --> b, b, bc, c, c. bc --> []. a --> [a]. b --> [b]. c -->…
Simon
  • 4,681
  • 21
  • 63
  • 92
6
votes
3 answers

Prolog - Generate alternating symbols on backtrack: [a] ; [a,b]; [a,b,a]; [a,b,a,b]

I've wrapped my mind a lot and couldn't figure it out. Is it possible to make a script that with backtrack generates lists in this format: [a] [a,b] [a,b,a] [a,b,a,b] ... I've made one that generates two elements at a time but my head started to…
6
votes
3 answers

how to split a sentence in swi-prolog

I am trying my hands on SWI-Prolog in win xp. I am trying to understand how to split a sentence in Prolog into separate atoms. Ex : Say I have a sentence like this : "this is a string" Is there any way to get individual words to get stored in a…
JPro
  • 5,696
  • 12
  • 53
  • 79
1 2
3
31 32