Prolog: DCG Syntax Error - prolog

I'm attempting to parse a "function call" for a language that I am creating, but I am getting:
:30:0 Syntax error: Operator expected
The first line below is where I am getting my error:
Fun(FXs) --> name(F),
ws,
[0'(],
ws,
args(Xs),
ws,
[0')],
{FXs =.. [F, Xs]}.
name(N) --> id(Cs),
{atom_chars(Cs, N)}.
I have exhaustively searched Google for help with errors in DCG parsing, and I have not found anything. An explanation on what I am doing wrong will be helpful, or any resources that would allow me to understand DCG more!

I guess it's Fun: you should write fun instead. SWI-Prolog has an extension to allow CamelCase functors, but must be enabled.

Related

semantics of verb-attached preposition phrases Prolog

I am trying to implement a verb-attached
preposition phrases in prolog.
So I've got:
VP -> Vbar
Vbar -> v, PP
PP -> Pbar
Pbar -> prep,np
the problem is when I try to phrase something like "Mary saw Tom with a telescope". There would be an error.
Can someone please give me some idea how to fix it?
Also can anyone please give me an idea how to implement the semantic of the Verb-attach prepositional phrase?
I do not know what the error is so I cannot say for sure, but the code you posted has a number of issues.
Prolog predicates must end in a period.
Prolog predicates begin with a lowercase letter.
You probably want to use -->, not ->. I am not sure what -> does, if anything at all.
I do not believe using strings would unify with any of your given predicates. You probably want to be using symbols, with ''.
You are using a bit of a weird syntax by including -->. You can find some information on it here. Because of this, if you want the symbol v to unify in your predicates you should write [v].
I am not sure if this code has the functionality you desire, but it does run:
vp --> vbar.
vbar --> [v], pp.
pp --> pbar.
pbar --> [prep,np].
You can call it like this:
vp([here, is, some, statement], []).

Prolog type errors with DCG library functions

I'm trying to write a DCG for a command interface. The idea is to read a string of input, split it on spaces, and hand the resulting list of tokens to a DCG to parse it into a command and arguments. The result of parsing should be a list of terms which I can use with =.. to construct a goal to call. However, I've become really confused by the string type situation in SWI-Prolog (ver. 7.2.3). SWI-Prolog includes a library of basic DCG functionality, including a goal integer//1 which is supposed to parse an integer. It fails due to a type error, but the bigger problem is that I can't figure out how to make a DCG work nicely in SWI-Prolog with "lists of tokens".
Here's what I'm trying to do:
:- use_module(library(dcg/basics)).
% integer//1 is from the dcg/basics lib
amount(X) --> integer(X), { X > 0 }.
cmd([show,all]) --> ["show"],["all"].
cmd([show,false]) --> ["show"].
cmd([skip,X]) --> ["skip"], amount(X).
% now in the interpreter:
?- phrase(cmd(L), ["show","all"]).
L = [show, all].
% what is the problem with this next query?
?- phrase(cmd(L), ["skip", "50"]).
ERROR: code_type/2: Type error: `character' expected, found `"50"' (a string)
I have read Section 5.2 of the SWI manual, but it didn't quite answer my questions:
What type is expected by integer//1 in the dcg/basics library? The error message says "character", but I can't find any useful reference as to what exactly this means and how to provide it with "proper" input.
How do I pass a list of strings (tokens) to phrase/2 such that I can use integer//1 to parse a token as an integer?
If there's no way to use the integer//1 primitive to parse a string of digits into an integer, how should I accomplish this?
I did quite a bit of expermenting with using different values for the double_quote flag in SWI-Prolog, plus different input formats, such as using a list of atoms, using a single string as the input, i.e. "skip 50" rather than ["skip", "50"], and so on, but I feel like there are assumptions about how DCGs work that I don't understand.
I have studied these three pages as well, which have lots of examples but none quite address my issues (some links omitted since I don't have enough reputation to post all of them):
The tutorial "Using Definite Clause Grammars in SWI-Prolog" by Anne Ogborn
A tutorial from Amzi! Prolog about writing command interfaces as DCGs.
Section 7.3 of J. R. Fisher's Prolog tutorial
A third, more broad question is how to generate an error message if an integer is expected but cannot be parsed as one, something like this:
% the user types:
> skip 50x
I didn't understand that number.
One approach is to set the variable X in the DCG above to some kind of error value and then check for that later (like in the hypothetical skip/1 goal that is supposed to get called by the command), but perhaps there's a better/more idiomatic way? Most of my experience in writing parsers comes from using Haskell's Parsec and Attoparsec libraries, which are fairly declarative but work somewhat differently, especially as regards error handling.
Prolog doesn't have strings. The traditional representation of a double quoted character sequence is a list of codes (integers). For efficiency reasons, SWI-Prolog ver. >= 7 introduced strings as new atomic data type:
?- atomic("a string").
true.
and backquoted literals have now the role previously held by strings:
?- X=`123`.
X = [49, 50, 51].
Needless to say, this caused some confusion, also given the weakly typed nature of Prolog...
Anyway, a DCG still works on (difference) lists of character codes, just the translator has been extended to accept strings as terminals. Your code could be
cmd([show,all]) --> whites,"show",whites,"all",blanks_to_nl.
cmd([show,false]) --> whites,"show",blanks_to_nl.
cmd([skip,X]) --> whites,"skip",whites,amount(X),blanks_to_nl.
and can be called like
?- phrase(cmd(C), ` skip 2300 `).
C = [skip, 2300].
edit
how to generate an error message if an integer is expected
I would try:
...
cmd([skip,X]) --> whites,"skip",whites,amount(X).
% integer//1 is from the dcg/basics lib
amount(X) --> integer(X), { X > 0 }, blanks_to_nl, !.
amount(unknown) --> string(S), eos, {print_message(error, invalid_int_arg(S))}.
prolog:message(invalid_int_arg(_)) --> ['I didn\'t understand that number.'].
test:
?- phrase(cmd(C), ` skip 2300x `).
ERROR: I didn't understand that number.
C = [skip, unknown] ;
false.

"operator expected after expression" when using dynamic openList/1

I'm trying to call the following at the top of my prolog file.
:- dynamic openList/1, dynamic closedList/1.
But this results in the following syntax error.
syntax error: . or operator expected after expression
I can't figure out what I'm doing wrong?
Thanks in advance.
In ISO Prolog only the following forms are legal:
:- dynamic(openList/1).
:- dynamic(closedList/1).
or
:- dynamic([openList/1,closedList/1]).
or (strangely, and not recommended)
:- dynamic((openList/1,closedList/1)).
Some Prologs will also allow (not portable)
:- dynamic openList/1, closedList/1.

Check a sentence for right syntax and get the semantic

i'm new to prolog and I try to program a answering machine. At first I like to figure out for what was asked, and to check correct syntax.
question(P) --> [where],[is], article(G,K,N), location(P,G,K,N).
location(P,G,K,N) --> [P], {member(P, [bakery, mcdonalds, kfc, embassy]),noun(G,K,N)}.
article(m, akk, sg) --> [a].
article(f, akk, sg) --> [an].
noun(m, akk, sg) --> [bakery]|[mcdonalds]|[kfc].
noun(f, akk, sg) --> [embassy].
but i got this error:
question(What, [where,is,a,bakery],[]).
ERROR: location/6: Undefined procedure: noun/3
ERROR: However, there are definitions for:
ERROR: noun/5
however, i found that the last two arguments of dcg variables are some kind of lists, but i really found nothing for that topic... do you have any tipps or solution for me?
PS: I tried to translate the example from german grammar, so don't be confused ;)
In the location rule, you put noun inside {} so it's treated like an ordinary Prolog rule. Take it outside the {} and your grammar "works" (well, the parse fails, but it doesn't throw an error).
location(P,G,K,N) --> [P], {member(P, [bakery, mcdonalds, kfc, embassy])},
noun(G,K,N).
a 'DCG predicate' has two 'hidden' arguments; noun(G,K,N) would be noun(G,K,N,L,R) where L would be the input list and R what is left after a noun has be recognised.
swi-prolog related man page
note that it's better to use the predicates phrase/[2,3] instead of using the equivalent predicate (the implementation could change).
as larsmans said, in this code noun should be outside {}

Declaring a predicate dynamic in gprolog

I have this code in Prolog:
dynamic(player_at/1).
player_at(house).
goto(X) :- retract(player_at(house)), assert(player_at(X)).
But I still get this error:
uncaught exception: error(permission_error(modify,static_procedure,player_at/1),retract/1)
when I execute goto(foo).
I've read the dynamic documentation, but I can't figure out how to use it, at least in gprolog. Am I missing something?
Fix the first line by prepending :-:
:- dynamic(player_at/1).
Without :- the line would dreefine predicate dynamic/1, instead of executing the existing dynamic predicate.
Other prolog implementations (but not gprolog) support this as well:
:- dynamic player_at/1.

Resources