How do you translate DCGs into normal definite clauses in PROLOG? - prolog

How would you translate the following DCGs into normal definite clauses of PROLOG?
expr_regular --> cor_ini,numero,guion,numero,cor_fin.
cor_ini --> ['['].
numero --> ['0'];['1'];['2'];['3'];['4'];['5'];['6'];['7'];['8'];['9'].
cor_fin --> [']'].
guion --> ['-'].
EDIT: I want to translate the DCG into normal PROLOG clauses cause I can't use both DCGs and normal clauses in the same code(in my case). I have this two pieces of code:
Piece1:
traducir(Xs, Ys) :- maplist(traduccion, Xs, Ys).
traduccion('^',comeza_por).
traduccion('[',inicio_rango).
traduccion('0',cero).
traduccion('-',a).
traduccion('9',nove).
traduccion(']',fin_rango).
An example of how to use it would be:
?- traducir(['[','0','-','9',']'],[]).
true .
And Piece2:
traducir--> cor_ini,numero,guion,numero,cor_fin.
cor_ini --> ['['].
numero --> ['0'];['1'];['2'];['3'];['4'];['5'];['6'];['7'];['8'];['9'].
cor_fin --> [']'].
guion --> ['-'].
An example of how to use it would be:
traducir(['^','[','0','-','9',']'],X).
X = [comeza_por, inicio_rango, cero, a, nove, fin_rango].
I want to join both codes into one to test if traducir is well written (if it follows the DCG) and to translate what you enter into text ,so the final program should able to do the following:
?- traducir(['^','[','0','-','9',']'],X).
X = [comeza_por, inicio_rango, cero, a, nove, fin_rango].
?- traducir(['[','0','-','9',']'],[]).
true .

In SWI-Prolog you can use listing/1 directly on the prolog-toplevel:
?- forall(member(NT,[expr_regular//0,cor_ini//0,numero//0,cor_fin//0,guion//0]),
listing(NT)).
expr_regular(A, F) :-
cor_ini(A, B),
numero(B, C),
guion(C, D),
numero(D, E),
cor_fin(E, F).
cor_ini(['['|A], A).
numero(A, B) :-
( A=['0'|B]
; A=['1'|B]
; A=['2'|B]
; A=['3'|B]
; A=['4'|B]
; A=['5'|B]
; A=['6'|B]
; A=['7'|B]
; A=['8'|B]
; A=['9'|B]
).
cor_fin([']'|A], A).
guion([-|A], A).
true.
That's it! You may profit from looking at the answers of the related question "Is there a way or an algorithm to convert DCG into normal definite clauses in Prolog?".

Your grammar it's exceptionally simple: just terminals. So we can translate to a very specific pattern (beware: no generalization allowed).
expr_regular(S, G) :-
S = [0'[, N1, 0'-, N2, 0']|G], numero(N1), numero(N2).
numero(N) :-
memberchk(N, "0123456789").
The only think worth to note it's ISO standard character notation...

Well I don't really get your question. Anyway, if you don't want to use the nice DCGs syntax for some reason you can still go with things like wildcard_match/2, or reinvent the wheel and use difference lists yourself to re-implement DCGs, or append. For the wildcard_match/2 part:
expr_regular(R) :- wildcard_match('[[][0-9]-[0-9]]', R).

Related

PROLOG - Get a list of all the rules an entity verifies

I'm formalizing linguistic data into predicates and entities and doing some reasoning in prolog. Imagine I begin with:
breathe(X) :- snore(X).
sleep(X) :- snore(X).
rest(X) :- sleep(X).
live(X) :- breathe(X); eat(X); sleep(X).
snore(john).
sleep(lucy).
My data can get big enough and I would like to get a list of entities and predicates in order to iterate them and check how many predicates an entity verifies, the output can be lists like:
[john, [snore, breathe, sleep, rest, live]]
[lucy, [sleep, rest]]
or predicates
participant(john, [snore, breathe, sleep, rest, live]).
participant(lucy, [sleep, rest]).
Thanks for your help, I have no clue at this moment.
Representing live knowledge about an abstract world can get messy. There are a lot of different possibilities, and a lot of variance depending of which Prolog system you're using.
Here is an example of your code running in SWI-Prolog, but the same idea should work (more or less) unchanged on any Prolog out there that provides call/N and setof/3 builtins.
:- module(list_entities_that_verify_a_pred,
[participant/2]).
:- redefine_system_predicate(sleep/1).
:- discontiguous breathe/1,sleep/1,rest/1,live/1,snore/1.
breathe(X) :- snore(X).
sleep(X) :- snore(X).
rest(X) :- sleep(X).
live(X) :- breathe(X); /* eat(X);*/ sleep(X).
snore(john).
sleep(lucy).
to_verify(breathe).
to_verify(sleep).
to_verify(rest).
to_verify(live).
to_verify(snore).
participant(Person,Verified) :-
setof(Pred,(to_verify(Pred),call(Pred,Person)),Verified).
First, note I have commented the call to eat/1, to avoid a missing definition exception, so we can try to call the partecipant/2 predicate:
?- participant(P,L).
P = john,
L = [breathe, live, rest, sleep, snore] ;
P = lucy,
L = [live, rest, sleep].
From an architecture viewpoint, the main point to note it's the introduction of to_verify/1, to ease the workflow.
An alternative is using forward chaining using Constraint Handling Rules, an underappreciated paradigm of computation.
This is done using SWI-Prolog's CHR library. The rule engine is implemented "on top of Prolog" and adding a rule to the "constraint store" looks like calling a Prolog goal. The "constraint store" holding the current state of computation disappears once the goal completes.
Note that I'm currently not 100% certain of CHR semantics (it seems my brain is hardwired to read Prolog now) but this code seems to work.
In file sleep.pl:
:- module(forward,[
snore/1,
sleep/1,
collect/2,
pull/2
]).
:- use_module(library(chr)).
:- chr_constraint snore/1, sleep/1, breathe/1.
:- chr_constraint eat/1, live/1, rest/1, collect/2, pull/2.
snore(X) ==> breathe(X).
snore(X) ==> sleep(X).
sleep(X) ==> rest(X).
breathe(X) ==> live(X).
eat(X) ==> live(X).
sleep(X) ==> live(X).
live(X) \ live(X) <=> true. % eliminates duplicates
collect(Who,L),snore(Who) <=> collect(Who,[snore|L]).
collect(Who,L),sleep(Who) <=> collect(Who,[sleep|L]).
collect(Who,L),breathe(Who) <=> collect(Who,[breathe|L]).
collect(Who,L),eat(Who) <=> collect(Who,[eat|L]).
collect(Who,L),live(Who) <=> collect(Who,[live|L]).
collect(Who,L),rest(Who) <=> collect(Who,[rest|L]).
pull(Who,L) \ collect(Who2,L2) <=> Who = Who2, L = L2.
Now we just need to start SWI-Prolog, and issue these commands:
?- [sleep].
true.
?- sleep(lucy),
collect(lucy,[]),
pull(Who,L).
Who = lucy,
L = [rest,live,sleep],
pull(lucy,[rest,live,sleep]).
?- snore(john),
collect(john,[]),
pull(Who,L).
Who = john,
L = [rest,live,breathe,sleep,snore],
pull(john,[rest,live,breathe,sleep,snore]).
You asked in a comment to Carlo's answer:
Is there a way to expose the eat predicate and the like? It looks like
I'm going to have a lot of unmatched predicate networks like owl and
proton because I'm going to use few facts and a lot of semantic
relations from Wordnet.
The issue here seems to be one of closed-world assumption (CWA) where predicates are declared (and thus can be called without generating errors) but not necessarily defined. In this case, as per CWA, what we cannot prove is true, is assumed to be false. E.g. the eat/1 predicate in your example or the "lot of unmatched predicate networks" in your comment.
A possible solution would be to define your entities as Logtalk objects that implement a protocol (or a set of protocols) that declare all the predicates you want to use. Reusing your example:
:- protocol(predicates).
:- public([
breathe/0, sleep/0, rest/0, live/0,
snore/0, eat/0
]).
:- end_protocol.
:- category(generic,
implements(predicates)).
breathe :- ::snore.
sleep :- ::snore.
rest :- ::sleep.
live :- ::breathe; ::eat; ::sleep.
:- end_category.
:- object(john, imports(generic)).
snore.
:- end_object.
:- object(lucy, imports(generic)).
sleep.
:- end_object.
If we ask an entity (object) about a predicate that it doesn't define, the query will simply fail. For example (using SWI-Prolog as backend here but you can use most Prolog systems; assuming the code above is saved in a code.lgt file):
$ swilgt
...
?- {code}.
...
?- lucy::eat.
false.
If we want to find all objects that satisfy e.g. the sleep/0 predicate:
?- findall(Object,
(current_object(Object),
conforms_to_protocol(Object, predicates),
Object::sleep),
Objects).
Objects = [john, lucy].
If we want to query all predicates satisfied by the objects (here with the simplifying assumption that all those predicates have zero arity):
?- setof(
Name,
Arity^(current_object(Object),
conforms_to_protocol(Object, predicates),
Object::current_predicate(Name/Arity),
Object::Name),
Predicates
).
Object = john,
Predicates = [breathe, live, rest, sleep, snore] ;
Object = lucy,
Predicates = [live, rest, sleep].
But, at least for the most common queries, handy predicate definitions would preferably be added to the generic category.
P.S. For more on the closed-world assumption and predicate semantics and also why Prolog modules fail to provide a sensible alternative solution see e.g. https://logtalk.org/2019/09/30/predicate-semantics.html

Skip/pass non-standard prolog code

I'm developing under SWI-Prolog, but my target is Erlog (https://github.com/rvirding/erlog). I need a way to use non-standard Prolog syntax.
Is there a way to write prolog code that will be disregarded by the SWI-compiler i.e. make it invisible.
Here is example how does it look like :
do_stuff(G,Amt) :- ecall(erlog_demo:efunc('Elixir.Blah':stuff({G,Amt})).
I was thinking if there is a way for SWI to skip that and I have another declaration that does nothing.
do_stuff(_,_).
One option probably is to comment it and then use parser to remove the comment before running in Erlog, but this seem cumbersome.
Any other ideas.
======
is_dialect(swi) :- catch(current_prolog_flag(dialect, swi), _, fail).
:- if(is_dialect(swi)).
do_stuff(_,_).
:- else.
do_stuff(G,Amt) :- ecall(erlog_demo:efunc('Elixir.Blah':stuff({G,Amt})).
:- endif.
Syntax error: Operator expected
I use this idiom to keep code running in different implementations
:- if(swi).
gen_hash_lin_probe(Key, HashTable, Value) :-
arg(_, HashTable, E),
nonvar(E),
E = Key-Value.
:- elif(yap).
gen_hash_lin_probe(Key, HashTable, Value) :-
HashTable =.. [htlp|Args],
nth1(_, Args, E),
nonvar(E),
E = Key-Value.
:- endif.
where predicates swi/0 or yap/0 are imported from this module(prolog_impl)
:- module(prolog_impl, [swi/0, yap/0, prolog_impl/1]).
swi :- prolog_impl(swi).
yap :- prolog_impl(yap).
prolog_impl(K) :-
F =.. [K,_,_,_,_],
current_prolog_flag(version_data, F).
One closing parenthesis is missing in the "else" branch.
do_stuff(G,Amt) :- ecall(erlog_demo:efunc('Elixir.Blah':stuff({G,Amt})). % BAD
do_stuff(G,Amt) :- ecall(erlog_demo:efunc('Elixir.Blah':stuff({G,Amt}))). % OK!
Simply count the number of opening parentheses. When . (period, full-step) is reached the difference count of opening vs closing must amount to exactly zero.
Hope that helps!
This answer is based, in part, on
#Capelli's answer and your comments on his candidate solution.
We propose a different way. Follow the dots step-by-step...
For a start, we take the following simplified and shortened snippet.
:- if(true). p(3).
:- elif(false). p(4+3).
:- endif.
In above sample we can see that the "else" branch is never taken, ever.
So... could we, in principle, put arbitrary text and binary data there?
:- if(true). p(3).
:- elif(false). p (4);;[ p())
:- endif.
нет! Upon (re-)loading, we get: ⚠ Syntax error: Operator expected
TIL that all sections between elif and endif must be valid Prolog text.
Let's try something different which was inspired by that phrases you used, in particular: "[...] use non-standard Prolog syntax [...] code that will be disregarded [...] make it invisible [...]"
To me, the phrase "non-standard syntax" indicates that new operator(s) might be introduced (or old ones redefined):
:- op(500,xfx,=>).
:- if(true). p(2).
:- elif(false). p(3 => 3).
:- endif.
Consider the following variation:
:- if(true). p(2).
:- elif(false). :- op(500,xfx,=>). % is moving the `op/3` here ok?
p(3 => 3).
:- endif.
нет! Upon (re-)loading, we get: ⚠ Unterminated conditional compilation from [...]
There is another way! We can proceed by inserting a special-purpose end_of_file fact to tell the Prolog text reader to disregard everything after end_of_file.
We use it like this:
% snip_at_end.pl
xxx1.
xxx2.
end_of_file.
xxx3.
:- op (500, xfx,eat). % broken syntax (pt.1)
1 ]][[ v % broken syntax (pt.2)
Simple test using SICStus Prolog:
$ sicstus
SICStus 4.3.2 (x86_64-linux-glibc2.12): Fri May 8 01:05:09 PDT 2015
[... License information ...]
| ?- compile(snip_at_end).
% compiling /home/stefan/prolog/snip_at_end.pl...
% compiled /home/stefan/prolog/snip_at_end.pl in module user, 40 msec 400672 bytes
yes
| ?- xxx1.
yes
| ?- xxx2.
yes
| ?- xxx3.
! Existence error in user:xxx3/0
! procedure user:xxx3/0 does not exist
! goal: user:xxx3
Hope this helps! I'm curious / interested if my answer fits your problem:)

Number of occurrences of X in the List L in prolog

I am trying to find the number of occurrences of X in the List L
For eg :-
occurrences(a, [b, a, b, c, a, d, a], N ).
N =3
My code not working .Here is my code.
occ(K,L,N) :- N1=0, occ1(K,L,N1,N).
occ1(K,[],N1,N) :- N=N1.
occ1(K,L,N1,N) :-
L=[X|L1],
( K=X -> N1 is N1+1, occ1(K,L1,N1,N) ; occ1(K,L1,N1,N) ).
Can anybody tell me what's wrong in the code.
While the answer given by #Kay is spot-on as far as fixing the bug is concerned, it completely circumvents a much bigger issue: The code of occ1/4 is logically impure.
This may not appear very important to you right now,
but using impure code has several negative consequences:
Impure code cannot be read declaratively, only procedurally.
Debugging impure code is often tedious and pain-staking.
Impure predicates are less "relational" than their pure counterparts.
Logical impurity hampers code re-use.
Because it is non-monotone, impure code is prone to lead to logically unsound answers, particularly when working with non-ground terms.
To show that these problems persisted in your code after having been "fixed" as suggested #Kay, let us consider the "corrected" code and some queries. First, here's the corrected code:
occ(K,L,N) :- N1=0, occ1(K,L,N1,N).
occ1(_,[],N1,N) :- N=N1.
occ1(K,L,N1,N) :-
L=[X|L1],
( K=X -> N2 is N1+1, occ1(K,L1,N2,N) ; occ1(K,L1,N1,N) ).
Here's the query you gave in your question:
?- occ(a,[b,a,b,c,a,d,a],N).
N = 3 ;
false.
Okay! What if we write the query differently?
?- A=a,B=b,C=c,D=d, occ(a,[B,A,B,C,A,D,A],N).
A = a, B = b, C = c, D = d, N = 3 ;
false.
Okay! What if we reorder goals? Logical conjunction should be commutative...
?- occ(a,[B,A,B,C,A,D,A],N), A=a,B=b,C=c,D=d.
false.
Fail! It seemed that occ1/4 is fine, but now we get an answer that is logically unsound.
This can be avoided by using logically pure code:
Look at the pure and monotone code I gave in my answer to the related question "Prolog - count repititions in list (sic)".
The problem is
N1 is N1+1
Variables cannot be "overwritten" in Prolog. You need to just a new variable, e.g.
N2 is N1+1, occ1(K,L1,N2,N)
To your question "Can we replace a particular list element. If yes, what is the syntax?":
You can only build a new list:
replace(_, _, [], []).
replace(Old, New, [H0|T0], [H1|T1]) :-
(H0 = Old -> H1 = New; H1 = H0),
replace(Old, New, T0, T1).

Prolog program to return atoms in a proposition formula

I am a newbie to prolog and am trying to write a program which returns the atoms in a well formed propositional formula. For instance the query ats(and(q, imp(or(p, q), neg(p))), As). should return [p,q] for As. Below is my code which returns the formula as As. I dont know what to do to split the single F in ats in the F1 and F2 in wff so wff/2 never gets called. Please I need help to proceed from here. Thanks.
CODE
logical_atom( A ) :-
atom( A ),
atom_codes( A, [AH|_] ),
AH >= 97,
AH =< 122.
wff(A):- ground(A),
logical_atom(A).
wff(neg(A)) :- ground(A),wff(A).
wff(or(F1,F2)) :-
wff(F1),
wff(F2).
wff(and(F1,F2)) :-
wff(F1),
wff(F2).
wff(imp(F1,F2)) :-
wff(F1),
wff(F2).
ats(F, As):- wff(F), setof(F, logical_atom(F), As).
First, consider using a cleaner representation: Currently, you cannot distinguish atoms by a common functor. So, wrap them for example in a(Atom).
Second, use a DCG to describe the relation between a well-formed formula and the list of its atoms, like in:
wff_atoms(a(A)) --> [A].
wff_atoms(neg(F)) --> wff_atoms(F).
wff_atoms(or(F1,F2)) --> wff_atoms(F1), wff_atoms(F2).
wff_atoms(and(F1,F2)) --> wff_atoms(F1), wff_atoms(F2).
wff_atoms(imp(F1,F2)) --> wff_atoms(F1), wff_atoms(F2).
Example query and its result:
?- phrase(wff_atoms(and(a(q), imp(or(a(p), a(q)), neg(a(p))))), As).
As = [q, p, q, p].
This should do what you want. It extracts the unique set of atoms found in any arbitrary prolog term.
I'll leave it up to you, though, to determine what constitutes a "well formed propositional formula", as you put it in your problem statement (You might want to take a look at DCG's for parsing and validation).
The bulk of the work is done by this "worker predicate". It simply extracts, one at a time via backtracking, any atoms found in the parse tree and discards anything else:
expression_atom( [T|_] , T ) :- % Case #1: head of list is an ordinary atom
atom(T) , % - verify that the head of the list is an atom.
T \= [] % - and not an empty list
. %
expression_atom( [T|_] , A ) :- % Case #2: head of listl is a compound term
compound(T) , % - verify that the head of the list is a compound term
T =.. [_|Ts] , % - decompose it, discarding the functor and keeping the arguments
expression_atom(Ts,A) % - recurse down on the term's arguments
. %
expression_atom( [_|Ts] , A ) :- % Finally, on backtracking,
expression_atom(Ts,A) % - we simply discard the head and recurse down on the tail
. %
Then, at the top level, we have this simple predicate that accepts any [compound] prolog term and extracts the unique set of atoms found within by the worker predicate via setof/3:
expression_atoms( T , As ) :- % To get the set of unique atoms in an arbitrary term,
compound(T) , % - ensure that's its a compound term,
T =.. [_|Ts] , % - decompose it, discarding the functor and keeping the arguments
setof(A,expression_atom(Ts,A),As) % - invoke the worker predicate via setof/3
. % Easy!
I'd approach this problem using the "univ" operator =../2 and explicit recursion. Note that this solution will not generate and is not "logically correct" in that it will not process a structure with holes generously, so it will produce different results if conditions are reordered. Please see #mat's comments below.
I'm using cuts instead of if statements for personal aesthetics; you would certainly find better performance with a large explicit conditional tree. I'm not sure you'd want a predicate such as this to generate in the first place.
Univ is handy because it lets you treat Prolog terms similarly to how you would treat a complex s-expression in Lisp: it converts terms to lists of atoms. This lets you traverse Prolog terms as lists, which is handy if you aren't sure exactly what you'll be processing. It saves me from having to look for your boolean operators explicitly.
atoms_of_prop(Prop, Atoms) :-
% discard the head of the term ('and', 'imp', etc.)
Prop =.. [_|PropItems],
collect_atoms(PropItems, AtomsUnsorted),
% sorting makes the list unique in Prolog
sort(AtomsUnsorted, Atoms).
The helper predicate collect_atoms/2 processes lists of terms (univ only dismantles the outermost layer) and is mutually recursive with atoms_of_prop/2 when it finds terms. If it finds atoms, it just adds them to the result.
% base case
collect_atoms([], []).
% handle atoms
collect_atoms([A|Ps], [A|Rest]) :-
% you could replace the next test with logical_atom/1
atom(A), !,
collect_atoms(Ps, Rest).
% handle terms
collect_atoms([P|Ps], Rest) :-
compound(P), !, % compound/1 tests for terms
atoms_of_prop(P, PAtoms),
collect_atoms(Ps, PsAtoms),
append(PAtoms, PsAtoms, Rest).
% ignore everything else
collect_atoms([_|Ps], Rest) :- atoms_of_prop(Ps, Rest).
This works for your example as-is:
?- atoms_of_prop(ats(and(q, imp(or(p, q), neg(p))), As), Atoms).
Atoms = [p, q].

How to input the following data in prolog?

not(A()) and not(D()) and not(B()) and not(A()).
What's the right way?
The concept of logical negation is already included in Prolog in means of failure. If your implementation doesn't supply it (it can happens) you can think not as
not(P) :- call(P), !, fail.
or
not(P) :- (call(P) -> fail ; true)
Then look at the formula, it can be simplified to have not applied just to single predicates:
~(A & ~D) & ~B & ~A = (~A | D) & ~B & ~A = ~A & ~B
It's just a De Morgan law and a consideration about the fact that D isn't useful to satisfability of the predicate.
then you can combine them:
final_predicate :- not(B), not(A).
EDIT: remember , is AND and ; is OR.
If simply trying to evaluate a propositional logic statement using PROLOG, you could try the following. Start with an encoding of the values of your 'propositions' a, b and d, such as:
a :- true. % this means that a is true.
b :- fail. % this means that b is false
...etc. For example, assuming your statements were:
a :- fail.
b :- fail.
d :- fail.
Then, executing your statement:
?- not(a), not(b), not(d), not(a).
true.
n.b.: The 'propositions' encoded here are 'simulated' - they're actually zero arity first-order predicates as far as PROLOG is concerned.
ps. a :- true. can be simplified to a..
pps. If I'm way off the mark and you're after a way of symbolically manipulating the statement into some other form, such as a normalization, then you need to write what is called a meta-interpreter in PROLOG. Refer to Clocksin and Mellish's Programming in Prolog, Appendix B, 'Clausal Form Program Listings', which might help you.

Resources