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...

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...

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)...

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.)...

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). ...

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...

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...

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...

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 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...

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...

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([], []). ...

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). %...

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]....

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,...