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
0
votes
0 answers

extract a class definition from a file using dcg in prolog

Can any one help me to generate a prolog grammar of a simple class definition. This is a sample dcg rule i have written. :- use_module(library(pio)). %classrule(Z) -->class,letter(X),letters(L),{name(Z,[X|L])}. classrule(Z) -->"class…
0
votes
0 answers

how to define (sometimes) recursive prolog trees

I've got two different types of sentences to parse, but i'll just give them simples names for now. Basically, I have two parse trees 1. A --> A , pp A --> dv, np 2. A --> tv, np I hope that makes sense, I just have no idea how to program this in…
0
votes
0 answers

Handling wide characters when parsing with DCGs

As I dig further into the use of DCGs, I find myself stymied by wide characters. I am trying to write a (more or less) general purpose tokenizer, and am testing its mettle against this text file of Macbeth (which I came across in a recent…
Shon
  • 3,989
  • 1
  • 22
  • 35
0
votes
2 answers

How to read a phrase from a url and what kind of stream does SWI-Prolog's `open_http/2` supply?

I am using the SWI-Prolog library(http/http_open). According to the docs, "After [http_open(Url, Stream, [])] succeeds the data can be read from Stream." Thus, I thought maybe I could rig up a simple, declarative predicate to parse phrases from…
Shon
  • 3,989
  • 1
  • 22
  • 35
0
votes
1 answer

SWI-Prolog conditional inclusion in html//1

I have some html segments that are dependant on some values being set in the session, is it possible to condition the inclusion in some way, so that I don't end up duplicating a massive chunk of html code? Or maybe there's another way to go about…
user900030
  • 68
  • 4
0
votes
1 answer

Issue with recursion not hitting base case

I'm working on the following DCG: zero(1) --> [0], !. zero(N) --> { N < 1 }, [], !. zero(N) --> zero(1), { M is N - 1 }, zero(M). It works properly for positive test cases, eg ?-…
user900030
  • 68
  • 4
0
votes
1 answer

Prolog DCG phrase error

I'm trying to understand what happens on this particular situation about Prolog DCG rules. The rules are: fizz_buzz(Msg) --> anything, fizz(Msg), anything, buzz, anything. anything --> []. anything --> [_], anything. fizz(Msg) --> "fizz", …
RRBaldi
  • 11
  • 4
0
votes
1 answer

Prolog sandwich predicate

I need to make a predicate sandwich(L) which is true if it has the same elements at the beginning and end of the list, like this: sandwich([a,a,b,c,d,a,a]). Could you please help me? Many thanks!
user3527255
0
votes
2 answers

right linear context free grammar

I've a problem. I have to write right linear context free grammar with alphapet={0,1} where the numbers of 0 will be even and the numbers od 1 will be odd. I tried write sth. but it's doesn't work. s --> [1],a. s --> [0],b. a --> []. a --> [1],c. a…
Vous
  • 67
  • 5
0
votes
0 answers

converting a list that contain an equation

I have a question regarding Prolog. Actually I have a Prolog function that call a list of numbers and signs and I want to convert the list from post equation to pre equation. for example if I have the list and the result to store the resulted…
user3281166
  • 29
  • 10
0
votes
2 answers

which sentences can this grammar generate?

Here is a tiny lexicon and a minigrammar consisting of one syntactic rule, I have to list all the sentences that this grammar can generate in the order that Prolog will generate them in, I know that the first sentence would be: a criminal eats a…
user3105533
  • 321
  • 3
  • 11
0
votes
2 answers

DCGs - how to split an atom into a list for further dcg rule processing

I have a simple grammar, which takes 3 list items and runs a different dcg rule on each. [debug] ?- phrase(sentence(X), [sky, a, 1], []). X = [bright, amber, on] . Code: sentence([A,C,R]) --> analyse(A), colour(C), …
magus
  • 1,347
  • 7
  • 13
0
votes
1 answer

Prolog, Grammar, Beginner

To implement s -> a ,with such a function rule(s,[a]) I came up with below code , but it doesn't work because of lower case s. if we had a grammar based on this format, how can I write the rule? format: grammar(Nonterminals, Terminals, Rules,…
Amir Nabaei
  • 1,582
  • 1
  • 15
  • 26
0
votes
1 answer

Prolog solving prefix arithmetic expression with unknown variable

I want to make an arithmetic solver in Prolog that can have +,-,*,^ operations on numbers >= 2. It should also be possible to have a variable x in there. The input should be a prefix expression in a list. I have made a program that parses an…
knordbo
  • 552
  • 3
  • 7
0
votes
3 answers

Trying to break elements which are lists in a list?

I am trying to write a program which make the following: ?- g([2,3, [22,[3],9] ,4,[5],99],X). X= [2,3,22,[3],9 ,4,5,99] So it searches for lists in the given list and replace it by their elements without brackets []. So I wrote this program: The…
user1780836