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
9
votes
4 answers

Recursive Prolog predicate for reverse / palindrome

Can I get a recursive Prolog predicate having two arguments, called reverse, which returns the inverse of a list: Sample query and expected result: ?- reverse([a,b,c], L). L = [c,b,a]. A recursive Prolog predicate of two arguments called…
sam
  • 91
  • 1
  • 2
9
votes
4 answers

How is this context free grammar using difference lists in Prolog functioning?

I'm reading this tutorial on context free grammars in Prolog, and they mention at the bottom of the page implementing a context free grammar in Prolog using difference lists, with the following code block included: s(X,Z):- np(X,Y), vp(Y,Z).…
Doug Smith
  • 29,668
  • 57
  • 204
  • 388
9
votes
2 answers

What does the "-" symbol mean in Prolog when dealing with lists?

I was reading the answer to this question, p(X) :- read(A), q(A,X-[]). q(end,X-X) :- !. q(A,[A|X]-Y) :- read(B), q(B,X-Y). The code above uses the syntax List-List. I somewhat understand what is going on, but I want to know what exactly what…
ivt
  • 301
  • 3
  • 9
8
votes
4 answers

Input in Prolog

I'm currently working on a recursive Prolog program to link routes together to create a basic GPS of the Birmingham area. At the moment I can get output as so: Input routeplan(selly_oak, aston, P). Output P = [selly_oak, edgbaston, ... ,…
Mike B
  • 12,768
  • 20
  • 83
  • 109
8
votes
2 answers

Is adaptive parsing possible in Prolog?

I am attempting to write an adaptive parser in Prolog: in other words, a parser that can modify its own parsing rules at runtime. In order to do this, I'll need to generate new predicates at runtime, but I'm not sure if this is possible. Would it be…
Anderson Green
  • 30,230
  • 67
  • 195
  • 328
8
votes
3 answers

Prolog getting head and tail of string

I'm trying to wrap my brain around Prolog for the first time (SWI-Prolog) and I'm struggling with what I'm sure are the basics. I'm trying to take a string such as "pie" and print out the military NATO spelling of it to look something like…
donsavage
  • 83
  • 1
  • 3
7
votes
3 answers

Prolog-based interpreter

I've already gotten my feet wet with functional programming; I am familiar (though not proficient) in Haskell and PLT Scheme. I've used PLT Scheme to build little interpreters for toy languages (referencing PLAI)--I'm better with imperative…
arkate
  • 501
  • 8
  • 23
7
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
  • 14,559
  • 5
  • 55
  • 51
7
votes
2 answers

Prolog DCGs Multiple Features?

From what I understand, in Prolog you capture features while parsing like so: foo(feature(X)) --> [X], bar. Is this common when designing DCGs ? foo(featureA(X), featureB(Y)) --> [X], [Y], bar.
dnolen
  • 18,496
  • 4
  • 62
  • 71
7
votes
2 answers

RegEx Parser written in Prolog

I've been banging my head against the wall on this homework problem for a few hours now. We have to parse a regular expression with Prolog. For the most part, the predicates I have work, but there's a few regular expression and string combos which…
mnuzzo
  • 3,529
  • 4
  • 26
  • 29
7
votes
2 answers

Prolog DCG set_prolog_flag double_quotes source code directive location matters; documentation?

I learned the hard way that with SWI-Prolog the location for the Prolog directive set_prolog_flag matters in a source code file. The only documentation I found of value about loading source code files with directives was in Loading Prolog source…
Guy Coder
  • 24,501
  • 8
  • 71
  • 136
7
votes
1 answer

Difficulties implementing DSL in Prolog from EBNF using DCG

I'm working on implementation of the Google Protobuf compiler for proto files in Prolog for generating Prolog programs. Prolog is SWI-Prolog. I'm translating EBNF definitions into DCG and ran across a few problems: I have to deal with [ ... ] and {…
Anton Danilov
  • 1,246
  • 11
  • 26
7
votes
4 answers

Solving Tower of Hanoi declaratively (Prolog)

My professor gave this as an example of Prolog. It is a program that solves the Tower of Hanoi puzzle, where you have to move a stack of disks to another peg by moving one disk after the other, without putting a bigger disk on top of a smaller disk.…
Bart Louwers
  • 873
  • 9
  • 28
7
votes
2 answers

Prolog DCG: Writing programming language lexer

I'm trying for the moment to keep my lexer and parser separate, based on the vague advice of the book Prolog and Natural Language Analysis, which really doesn't go into any detail about lexing/tokenizing. So I am giving it a shot and seeing several…
Daniel Lyons
  • 22,421
  • 2
  • 50
  • 77
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,715
  • 5
  • 21
  • 29
1
2
3
32 33