Why is this rule not consuming the first character [Prolog CFG]? - parsing

I am trying to write a rule for wrapping elements but when entering the recursive rule, the first element is still being included, maybe I am not understanding correctly the syntax but the comma shouldn't go to the next element?
% [First] should be consumed (note: charcode 194 is for the backtick character)
backticks(L) --> [First], {char_code(First,194), writeln(["first was backtick",First])}, nobackticks(L), {writeln(["identifier",L])}.
nobackticks([]) --> [Last], {char_code(Last,194),writeln(["last is backtick",Last])}.
nobackticks([X|Xs]) --> [X], nobackticks(Xs), {writeln(["checking backticks",X,Xs])}.
%run recursively until it finds the last backtick
Test
:- string_chars("´backticks´",Text), phrase(backticks(X),Text,[]), writeln(X).
Output:
[first was backtick,´]
[last is backtick,´]
[checking backticks,s,[]]
[checking backticks,k,[s]]
[checking backticks,c,[k,s]]
[checking backticks,i,[c,k,s]]
[checking backticks,t,[i,c,k,s]]
[checking backticks,k,[t,i,c,k,s]]
[checking backticks,c,[k,t,i,c,k,s]]
[checking backticks,a,[c,k,t,i,c,k,s]]
[checking backticks,b,[a,c,k,t,i,c,k,s]]
[checking backticks,´,[b,a,c,k,t,i,c,k,s]]
[identifier,[´,b,a,c,k,t,i,c,k,s]]
Expected output:
[identifier,[b,a,c,k,t,i,c,k,s]]
Finally the rule is not successful

If you run ?- char_code(´,C). you get C=180 (at least in SWISH). So you need to change 194 to 180 in your code and you will get the desired output:
[first was backtick, ´]
[last is backtick, ´]
[checking backticks, s, []]
[checking backticks, k, [s]]
[checking backticks, c, [k, s]]
[checking backticks, i, [c, k, s]]
[checking backticks, t, [i, c, k, s]]
[checking backticks, k, [t, i, c, k, s]]
[checking backticks, c, [k, t, i, c, k, s]]
[checking backticks, a, [c, k, t, i, c, k, s]]
[checking backticks, b, [a, c, k, t, i, c, k, s]]
[identifier, [b, a, c, k, t, i, c, k, s]]
[b, a, c, k, t, i, c, k, s]
true
false

Related

Natural Language processing with prolog error

I'm new to using prolog and I'm trying things to get a text parsed and translated in this way:
?- go.
|: All boys run.
s(np(det(all),noun(boys)),vp(verb(run)))
S = all(_4326, boy(_4326)->run(_4326))
but I'm having an error: I run go. to get the translation, I get the following error:
go.
|: All boys run
**ERROR: Stream user_input:242:4 Syntax error: Operator expected**
Here is my code.
% Tokenizer
go1(Out):-
read(X),
name(X,L),
tokenize(L,Out).
tokenize([],[]):- !.
tokenize(L,[Word|Out]):- L\==[],
tokenize(L,Rest,WordChs),
name(Word,WordChs),
tokenize(Rest,Out).
tokenize([],[],[]):- !.
tokenize([46|_],[],[]):- !.
tokenize([32|T],T,[]):- !.
tokenize([H|T],Rest,[H|List]):-
tokenize(T,Rest,List).
% Main predicate
go :-
%go1(X),
readln(X, _, _, _, lowercase),
reset_gensym,
sentence(P, X, []),
translator(P, R),
write(R).
%Operator's definition
:- op(600,xfy,=>).
:- op(500,xfy,&).
%Grammar + Parser
sentence(sentence(NP, VP)) --> noun_phrase(Num, NP), verb_phrase(Num, VP).
%test cases
% All boys run
% All boys like all watermelons that contain some divine flavor
% Some boy eats some apple
% Some government conscripts some pacifist people
% All government that conscripts pacifist people are evil
noun_phrase(Num, np(DET, N)) --> determiner(Num, DET), noun(Num, N).
noun_phrase(Num, np(ADJ, N)) --> adjective(ADJ), noun(Num, N).
noun_phrase(Num, np(DET, ADJ, N)) --> determiner(Num, DET), adjective(ADJ), noun(Num, N).
noun_phrase(Num, np(DET, N, RCL)) --> determiner(Num, DET), noun(Num, N), relative_clause(Num, RCL).
noun_phrase(Num, np(N)) --> noun(Num, N).
verb_phrase(Num, vp(V)) --> verb(Num, itrans, V).
verb_phrase(Num, vp(V, NP)) --> verb(Num, trans, V), noun_phrase(_, NP).
verb_phrase(Num, vp(BV, ADJ)) --> beVerb(Num, BV), adjective(ADJ).
relative_clause(Num, rcl(REL, VP)) --> rel(REL), verb_phrase(Num,VP).
relative_clause(Num, rcl(REL, NP, V)) --> rel(REL), noun_phrase(Num,NP), verb(Num, itrans, V).
adjective(adj(good)) --> [good].
adjective(adj(evil)) --> [evil].
adjective(adj(big)) --> [big].
adjective(adj(divine)) --> [divine].
adjective(adj(pacifist)) --> [pacifist].
adjective(adj(nice)) --> [nice].
is_det(plural, all).
is_det(singular, a).
is_det(_, the).
is_det(_, some).
determiner(Num, determiner(D)) --> [D], {is_det(Num, D)}.
is_noun(plural, boys).
is_noun(singular, boy).
is_noun(plural, girls).
is_noun(singular, girl).
is_noun(plural, people).
is_noun(singular, person).
is_noun(plural, apples).
is_noun(singular, apple).
is_noun(plural, watermelons).
is_noun(singular, watermelon).
is_noun(plural, rabbits).
is_noun(plural, carrots).
is_noun(plural, evil).
is_noun(plural, governments).
is_noun(singular, government).
is_noun(singular, flavor).
noun(Num,noun(N)) --> [N], {is_noun(Num,N)}.
is_verb(plural, trans, like).
is_verb(singular, trans, likes).
is_verb(plural, _, eat).
is_verb(singular, _, eats).
is_verb(plural, itrans, run).
is_verb(singular, itrans, runs).
is_verb(plural, trans, contain).
is_verb(singular, trans, contains).
is_verb(plural, trans, conscript).
is_verb(singular, trans, conscripts).
verb(Num, Tp, v(V)) --> [V], {is_verb(Num, Tp, V)}.
beVerb(plural, bv(tastes)) --> [taste].
beVerb(plural, bv(iss)) --> [are].
beVerb(singular, bv(iss)) --> [iss].
beVerb(singular, bv(sounds)) --> [sounds].
rel(rel(that)) --> [that].
% Rules for translator
translator(sentence(NP,VP),F) :-
% genera un unico atomo de la X y lo unifica en Var
gensym(x,Var),
np(Var,NP,T),
vp(Var,T,VP,F).
% Translation of noun phrase
np(Var, np(DET,N), R) :-
n(Var, N, P1),
det(DET, P1, R).
np(Var, np(DET,ADJ,N), R) :-
adj(Var, ADJ, P1),
n(Var, N, P1, P2),
det(DET, P2, R).
np(Var, np(ADJ, N), R) :-
adj(Var, ADJ, P1),
n(Var, N, P1, R).
np(Var, np(DET, N, RCL), R) :-
n(Var, N, P1),
rcl(Var, RCL, P1, P2),
det(DET, P2, R).
np(Var, np(N), R) :-
n(Var, N, R).
rcl(Var, rcl(_, VP), T, R) :- vp(Var, T, VP, R).
% This predicate add an implication or conjuction between F1 and F2
q_join(all, V, F1, F2, all(V, F1 => F2)).
q_join(exists, V, F1, F2, exists(V, F1 & F2)).
% Translation of verb phrase
vp(Var, P, vp(V), R) :-
P =.. [Q, V1, F1],
v(Var, V, C),
q_join(Q, V1, F1, C, R).
vp(Var, P, vp(bv(BVERB), adj(ADJ)), R) :-
P =.. [Q, V1, F1],
C =.. [BVERB, Var, ADJ],
q_join(Q, V1, F1, C, R).
vp(Var, P, vp(V, NP), R) :-
P =.. [Q1, V1, F1],
gensym(x,X),
v(Var, X, V, C),
np(X, NP, T),
T =.. [Q2, V2, F2],
q_join(Q2, V2, F2, C, R1),
q_join(Q1, V1, F1, R1, R).
% Terminals symbols, they create functors
det(determiner(all), P, R) :-
P =.. [_, V, F],
R =.. [all, V, F],
!.
det(determiner(_), P, P).
n(Var, noun(N), exists(Var, P)) :- P =.. [N, Var].
n(Var, noun(N), A, exists(Var, (P & A))) :- P =.. [N, Var].
v(Var, v(V), P) :- P =.. [V, Var].
v(V1, Var, v(V), P) :- P =.. [V, V1, Var].
adj(Var,adj(ADJ),P) :- P =.. [ADJ, Var].

Query Filter Results

I am trying to query and then filter my results based on the drop down in N4
=
IF(and(N4="ALL"), query(Vendors!1:1000,"select A, B, C, D, E, F, G, H, I, J, K, L", 2),
IF(and(N4="Trained"), query(Vendors!1:1000,"select A, B, C, D, E, F, G, H, I, J, K, L", 2),
IF(and(N4="Requested"), query(Vendors!1:1000,"select A, B, C, D, E, F, G, H, I, J, K, L", 2),
IF(and(N4="Invited"), query(Vendors!1:1000,"select A, B, C, D, E, F, G, H, I, J, K, L", 2)))))
Those all return results. However, now I need help omitting the results that dont match the dropdown.
Sorry I didn't read it correctly. Try this.
=IF (N4 <>"ALL",IF(OR(OR( N4="Trained",N4="Requested",N4="Invited")),query(Vendors!1:1000,"select A, B, C, D, E, F, G, H, I, J, K, L where A = '"& N4 &"'")),query(Vendors!2:1000,"select A, B, C, D, E, F, G, H, I, J, K, L where A<>''"))
Key in the Header row. Change Column A to whatever column "Trained", "Invited", etc are in.

MergeSort and Quicksort in Erlang not working

Can someone help me figure out what's wrong with my sorting algorithms. I get no errors but get stuck in some kind of infinite loop. The functions seem to work individually.
msort([])->
[];
msort(L)->
{L3, L4} = msplit(L, [],[]),
merge(msort(L3), msort(L4)).
msplit([], L1, L2)->
{L1, L2};
msplit([H|[]], L1, L2)->
msplit([], [H]++L1, L2);
msplit([H|[H2|T]], A, B)->
msplit(T, A++[H], B++[H2]).
merge(L, [])->L;
merge([], R)->R;
merge([H1|T1], [H2|T2])->
if H1 < H2
-> [H1|merge(T1, [H2|T2])];
true-> [H2|merge([H1|T1], T2)]
end.
qsort([])->[];
qsort([H|T])->
{A, B} =qsplit(T, H, [], []),
Small =qsort(A),
Large = qsort(B),
lists:append(Small,Large).
qsplit([], H, A, B)->
{A++[H], B};
qsplit([H|T], P, A, B)->
if H > P->
qsplit(T, P, A++[H], B);
true-> qsplit(T, P, A, B++[H])
end.
After some changes the code is working properly:
msort([]) ->
[];
msort([_] = L) ->
L;
msort(L)->
{L3, L4} = msplit(L, [],[]),
merge(msort(L3), msort(L4)).
msplit([], L1, L2)->
{L1, L2};
msplit([H|[]], L1, L2)->
msplit([], [H|L1], L2);
msplit([H|[H2|T]], A, B)->
msplit(T, [H|A], [H2|B]).
merge(L, [])->L;
merge([], R)->R;
merge([H1|T1], [H2|T2])->
if H1 < H2
-> [H1|merge(T1, [H2|T2])];
true-> [H2|merge([H1|T1], T2)]
end.
qsort([])->[];
qsort([_] = L)->L;
qsort([H|T])->
{A, B} =qsplit(T, H, [], []),
Large =qsort(A),
Small = qsort(B),
lists:append(Small,[H|Large]).
qsplit([], _, A, B)->
{A, B};
qsplit([H|T], P, A, B)->
if H > P->
qsplit(T, P, [H|A], B);
true-> qsplit(T, P, A, [H|B])
end.
If you call msort/1 with a list containing just one item [X] your msplit/1 will return {[X], []} where you call msort/1 with one item [X] and so on. You can fix it by adding msort/1 function clause:
msort([])->
[];
msort([_] = L) ->
L;
msort(L)->
...
A similar problem is in your qsort/1.
There are more problems in your code. You should replace all your A++[H] with [H] ++ A which is even better written as [H|A]. It has big impact to an efficiency of your code. You can use [H, H2 | T] instead of [H | [H2 | T]], it is nice syntactic sugar which helps readability.

Erlang: proplists:get_value/2 or pattern matching?

I have a list of tuples that has always the same form (i.e. the tuples come always in the same order):
1> L = [{a, 1}. {b,2}, {c, 3}, {d, 4}].
Knowing that the list has only a few elements, what is the best way to extract the values associated to the keys?
Suppose the list is passed as argument to a function, to extract the values should I use:
proplists:get_value(a, L).
proplists:get_value(b, L).
...
proplists:get_valus(d, L).
Or should I simply use pattern matching as:
[{a, 1}. {b,2}, {c, 3}, {d, 4}] = L.
If you really know your lists is in same form pattern matching is simplest
[{a, A}, {b, B}, {c, C}, {d, D}] = L,
you can compare it with following
[A, B, C, D] = [ proplists:get_value(X, L) || X <- [a,b,c,d] ],
or
A = proplists:get_value(a, L),
B = proplists:get_value(b, L),
C = proplists:get_value(c, L),
D = proplists:get_value(d, L),
or
[A, B, C, D] = [ V || Key <- [a,b,c,d], {K, V} <- L, K =:= Key ],
Pattern matching will be also fastest. You can also use lists:keyfind/3 which is implemented as Bif and is way faster than proplist:get_value/2 but it doesn't matter for short lists.

Scala parser combinators for (almost) trivial grammar

I've been trying to make a parser for a (very) simple language that looks like this:
block{you are a cow too blkA{ but maybe not} and so is he} hear me moo blockZ{moooooo}
I can break it apart using regexes:
.*?[^ ]*?\\{
.*?\\}
which would essentially keep eating characters until it found something that matches [^ ]*?\\{ or \\}: the start or end of a block. My question is, if I want to do it using Scala's Parser Combinators, how do I do that? I currently have:
def expr: Parser[Any] = (block | text)+
def text = ".+?".r
def block = "[^ ]*?\\{".r ~ expr ~ "}"
but this doesn't work:
parsed: List(b, l, o, c, k, {, y, o, u, a, r, e, a, c, o, w, t, o, o, b, l, k, A, {, b, u, t, m, a, y, b, e, n, o, t, }, a, n, d, s, o, i, s, h, e, }, h, e, a, r, m, e, m, o, o)
It seems that the block parser is not firing, and so the text parser is being fired repeatedly. but when i remove the text parser:
def expr: Parser[Any] = (block)+
I get:
failure: string matching regex `[^ ]*?\{' expected but `y' found
block{you are a cow too blkA{ but maybe not} and so is he} hear me moo
^
So obviously the block parser does work, except not when the text parser is present. What's happening? and is there a "proper" way of doing this, for so basic a grammar?
EDIT: Changed the title, since it's not so much about the reluctance anymore as just solving the problem
EDIT: I now have this:
def expr: Parser[Any] = (block | text)+
def text = "[^\\}]".r
def block = "[^ ]*?\\{".r ~ expr ~ "}"
The logic behind this is that for each character, it tests whether or not it is the start of a block. If it isn't, it moves on to the next character. This gives me:
parsed: List(((block{~List(y, o, u, a, r, e, a, c, o, w, t, o, o, ((blkA{~List(b, u, t, m, a, y, b, e, n, o, t))~}), a, n, d, s, o, i, s, h, e))~}), h, e, a, r, m, e, m, o, o)
which is kind of correct. It is parsing the non-block characters one-by-one though, which is probably a performance problem (i think?). Is there any way to parse all those non-block characters at once and leave them in one big string?
The problem is that text is consuming all closing curly braces (}). It goes like this:
expr -> block -> expr -> text.+ (until all input is consumed)
At this point, it exits expr and tries to parse }, which does not exists, fails, and falls back to text on the first expr.
You can use log to see what's going on when you parse.

Resources