your grammar seems fine, but you forgot to handle/skip blanks ?- phrase(g(X), `-(a+b)*(b+-a)`). X = and(not(or(a, b)), or(b, not(a))) ; false. (note: I've manually removed all blanks, and used SWI-Prolog extensions for list of codes literal.)...

Although false's answer is more elegant, here is a solution more appropriate for beginners for your predicate u/2. u([X,Y|_], [X,Y]). u([_|Tail], XY):- u(Tail,XY). The first rule says that [X,Y] represent two consecutive elements in a list if they are the first two elements in that list. The second rule states...

Since you're not required to evaluate the expression, the code could be expr(lit(_)). expr(add(E1,E2)) :- expr(E1), expr(E2). expr(sub(E1,E2)) :- expr(E1), expr(E2). ...

This is a nice application for Prolog grammar rules or DCGs (basically syntactic sugar that hides some list manipulation and has a relatively straightforward translation to normal Prolog rules). num_0_999(0) --> [zero]. num_0_999(N) --> num_1_99(N). num_0_999(N) --> num_100_999(N). num_1_99(N) --> num_1_9(N). num_1_99(N) --> num_10_19(N). num_1_99(N) --> decade(T), opt_1_9(U), {N is...

In Prolog, you cannot reassign variables. So expressions such as R is R // 2 will fail since, in Prolog, it semantically says that *R is itself integer divide by 2 which would only be true if R was 0. Likewise, given that a Tape is a list, you cannot...

Consider first a pure solution, using DCGs to translate a list of things a person likes to a list of formatting instructions that can later be interpreted: person_likes(Who, Whats) --> atom(Who), atom(': '), likes_(Whats). likes_([]) --> [newline]. likes_([X]) --> atom(X), [newline]. likes_([X,Y|Rest]) --> atom(X), atom(', '), likes_([Y|Rest]). atom(A) --> [atom(A)]....

I think your problem is over-specified, and you don't want the cuts. In particular, you don't need the "negative" case: zero(N) --> { N < 1 }, [], !. This will SUCCEED on what you consider to be a failure case. Instead, try something a little simpler: zero(1) --> [0]....

I figured it out by putting the logic in another DCG and include it in html//1. ( { http_session_data(Data) } -> div(p('I''m only displayed when there''s session data')) ; {true} ) The {true} part is to get rid of an error message in the console. However, I've since changed my...

algorithm,parsing,prolog,grammar,dcg

You are on the right track! Keep on going and you will get to something like this: expr(Xs0,Xs) :- % expr --> term(Xs0,Xs1), % term, addterm(Xs1,Xs). % addterm. addterm(Xs0,Xs) :- % addterm --> Xs0 = Xs. % []. addterm(Xs0,Xs) :- % addterm --> Xs0 = [+|Xs1], % [+], expr(Xs1,Xs). %...

list,prolog,palindrome,dcg,difference-lists

Use a definite clause grammar! palindrome --> []. palindrome --> [_]. palindrome --> [X],palindrome,[X]. As an alternative we could also write: palindrome --> [] | [_] | [X],palindrome,[X]. dcg offer an automatic way of using difference-lists. On the prolog-toplevel we use the builtin listing/1 to get the code the DCG...

Here is probably the dcg you meant: :- set_prolog_flag(double_quotes, chars). expression --> number. expression --> variable. expression --> "(", expression, operator, expression, ")". number --> digit. number --> digit, number. digit --> "1". digit --> "2". digit --> "3". operator --> "+"|"-"|"*". % more compact notation variable --> "X"|"Y"|"Z". Use...

I'll try to answer on SWISH, on this snippet Here is the code, in case the link is volatile... :- use_module(library(dcg/basics)). atom_ipv4(A, IPV4) :- atom_codes(A, Cs), phrase(ipv4(IPV4), Cs). ipv4(D) --> dotted(D). ipv4(range(D, R)) --> dotted(D), "/", integer(R). dotted(address(A, B, C, D)) --> octet(A), ".", octet(B), ".", octet(C), ".", octet(D). octet(A)...

One problem in the original attempt is this query: findMaxTotal(Rest,Y,max(Ret,X)). Prolog does not evaluate arithmetic expressions when processing query arguments. The max/2 must appear, at some point, in the second argument of an is/2 or in an arithmetic comparator to be evaluated. The fix-up of the original code, which is...

Here's an enhancement of your parser as written which can get you started. It's an elaboration of the notions that @CapelliC indicated. parser([]) --> []. parser(Tree) --> assign(Tree). assign([assignment, ident(X), '=', Exp]) --> id(X), [=], expr(Exp), [;]. id(X) --> [X], { atom(X) }. expr([expression, Term]) --> term(Term). expr([expression, Term, Op,...

Could be just: swap(A, B) :- append([First | Mid], [Last], A), append([Last | Mid], [First], B). Additional facts to succeed with one element and empty lists, if it's needed: swap([X], [X]). swap([], []). ...