Skip/pass non-standard prolog code - prolog

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

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

Prolog - print true or false in print_solution write method

I want to print true or false based on some predicate predicate passing. For example, in Greek mythology Athena is not a descendant of Poseidon. I have all of the facts and rules correct to prove it as such, but cannot simply print in the print_solution method whether the predicate is true or not.
I have the rule descendant(athena, poseidon) that will print false in the interpreter as a single statement. E.g. false is printed if I:
$ prolog
['greek_mythology.pl'].
descendant(athena, poseidon).
false
I now want to write the same in my print_solution method:
print_solution :-
write('Athena is a descendant of Poseidon: '), write(?????), nl.
I tried assigning a variable in the solution and printing that:
print_solution :-
Z :- descendant(athena, poseidon),
write('Athena is a descendant of Poseidon: '), write(Z), nl.
but I get the error:
ERROR: /.../greek_mythology.pl:164:17: Syntax error: Operator priority clash
Out of desperation I tried checking to see if poseidon was in the list of descendant(athena, X):
setof(X, descendant(athena, X), Z), // [gaia,kronos,oranos,rheia,zeus]
member(poseidon, Z).
but that just gives back:
Z = [poseidon|_G3320] .
which I don't understand. Apparently member/2 only works on lists, and Z is apparently not a list:
is_list(Z).
false.
How can I simply print true or false in the write function if the predicate returns passes like it does in the interpreter console? Desired output: Athena is a descendant of Poseidon: false.
You can use if/then/else construct in Prolog also
print_solution :-
( descendant(athena, poseidon)
-> Z = true
; Z = false
),
write('Athena is a descendant of Poseidon: '), write(Z), nl.
seems also could be more useful if parametrized
print_solution(Desc, Anc) :-
( descendant(Desc, Anc)
-> Z = true
; Z = false
),
format('~w is a descendant of ~w: ~w~n', [Desc, Anc, Z]).
print_solution :- print_solution(athena, poseidon).
I think (not absolutely sure) that what you want is reification of the success or failure of a query to a truth value. A naive way to do it would be:
goal_success(Goal, true) :-
Goal.
goal_success(Goal, false) :-
\+ Goal.
(This has problems but read on)
Then, you can use it like this:
?- goal_success(descendant(athena, poseidon), S),
/* write whatever */, write(S).
However, what you are trying to do is basically write your own meta-interpreter, and I am not sure it is really that useful. After all, what you show in your question is exactly how you would expect to interact with the Prolog top level (the Prolog interactive prompt). As a programmer (a human) what you want from Prolog is answers to your questions. What you give Prolog, however, is queries, and you get solutions to these queries. Your question is:
Is Athena a descendant of Poseidon?
You evaluate the query:
?- descendant(athena, poseidon).
false.
There is no solution to this query (let's not go into the whole "closed world assumption" discussion now, it is enough to say that not being able to find a proof means that the opposite is true...)
So we interpret this as:
Athena is not a descendant of Poseidon.
Usually, this should be enough. This is why it seems that you want to extend the Prolog top level, and write your own interpreter on top of it, which is of course fine, but more involved. Once you go down that road, you would like to interact with this interpreter like this maybe?
??- Is Athena a descendant to Poseidon?
?>> No, she is not!
Anyway, if you search the internet for "Prolog meta interpreter" you will get enough to get you started. "The Art of Prolog" by Sterling & Shapiro has a whole chapter on that, too.

A DCG that matches the rest of the input

This is the predicate that does what it should, namely, collect whatever is left on input when part of a DCG:
rest([H|T], [H|T], []).
rest([], [], []).
but I am struggling to define this as a DCG... Or is it at all doable?
This of course is not the same (although it does the same when used in the same manner):
rest([H|T]) --> [H], !, rest(T).
rest([]) --> [].
The reason I think I need this is that the rest//1 is part of a set of DCG rules that I need to parse the input. I could do phrase(foo(T), Input, Rest), but then I would have to call another phrase(bar(T1), Rest).
Say I know that all I have left on input is a string of digits that I want as an integer:
phrase(stuff_n(Stuff, N), `some other stuff, 1324`).
stuff_n(Stuff, N) -->
stuff(Stuff),
rest(Rest),
{ number_codes(N, Rest),
integer(N)
}.
Answering my own silly question:
#CapelliC gave a solution that works (+1). It does something I don't understand :-(, but the real issue was that I did not understand the problem I was trying to solve. The real problem was:
Problem
You have as input a code list that you need to parse. The result should be a term. You know quite close to the beginning of this list of codes what the rest looks like. In other words, it begins with a "keyword" that defines the contents. In some cases, after some point in the input, the rest of the contents do not need to be parsed: instead, they are collected in the resulting term as a code list.
Solution
One possible solution is to break up the parsing in two calls to phrase/3 (because there is no reason not to?):
Read the keyword (first call to phrase/3) and make it an atom;
Look up in a table what the rest is supposed to look like;
Parse only what needs to be parsed (second call to phrase/3).
Code
So, using an approach from (O'Keefe 1990) and taking advantage of library(dcg/basics) available in SWI-Prolog, with a file rest.pl:
:- use_module(library(dcg/basics)).
codes_term(Codes, Term) :-
phrase(dcg_basics:nonblanks(Word), Codes, Codes_rest),
atom_codes(Keyword, Word),
kw(Keyword, Content, Rest, Term),
phrase(items(Content), Codes_rest, Rest).
kw(foo, [space, integer(N), space, integer(M)], [], foo(N, M)).
kw(bar, [], Text, bar(Text)).
kw(baz, [space, integer(N), space], Rest, baz(N, Rest)).
items([I|Is]) -->
item(I),
items(Is).
items([]) --> [].
item(space) --> " ".
item(integer(N)) --> dcg_basics:integer(N).
It is important that here, the "rest" does not need to be handled by a DCG rule at all.
Example use
This solution is nice because it is deterministic, and very easy to expand: just add clauses to the kw/4 table and item//1 rules. (Note the use of the --traditional flag when starting SWI-Prolog, for double-quote delimited code lists)
$ swipl --traditional --quiet
?- [rest].
true.
?- codes_term("foo 22 7", T).
T = foo(22, 7).
?- codes_term("bar 22 7", T).
T = bar([32, 50, 50, 32, 55]).
?- codes_term("baz 22 7", T).
T = baz(22, [55]).
An alternative (that doesn't leave a choice point behind) is to use the call//1 built-in non-terminal with a lambda expression. Using Logtalk's lambda expression syntax to illustrate:
rest(Rest) --> call({Rest}/[Rest,_]>>true).
This solution is a bit nasty, however, as it uses a variable with a dual role in the lambda expression (which triggers a warning with the Logtalk compiler). An usage example:
:- object(rest).
:- public(test/2).
test(Input, Rest) :-
phrase(input(Rest), Input).
input(Rest) --> [a,b,c], rest(Rest).
rest(Rest) --> call({Rest}/[Rest,_]>>true).
% rest([C|Cs]) --> [C|Cs]. % Carlo's solution
:- end_object.
Assuming the above object is saved in a dcg_rest.lgt source file:
$ swilgt
...
?- {dcg_rest}.
* Variable A have dual role in lambda expression: {A}/[A,B]>>true
* in file /Users/pmoura/Desktop/dcg_rest.lgt between lines 13-14
* while compiling object rest
% [ /Users/pmoura/Desktop/dcg_rest.lgt loaded ]
% 1 compilation warning
true.
?- rest::test([a,b,c,d,e], Rest).
Rest = [d, e].
You should be able to get the same results using other lambda expressions implementation such as Ulrich's lambda library.
could be
rest([C|Cs]) --> [C|Cs] .
at least in SWI-Prolog, it seems to run (I used library(dcg/basics) to get the number)
line(I,R) --> integer(I), rest(R).
?- phrase(line(N,R), `6546 okok`).
N = 6546,
R = [32, 111, 107, 111, 107]

how can I print items in a list one by one

I have my answers in a list by findall and the list is called answers.
Now answers can have 0 , 1 or more items.
0 answer I can solve with display_answers([]).
1 answer I can solve with display_answer ([X]).
Can I do more then 1 display_answer([X|X]) and then use foreach to print all the answers ?
Or is there a better way ?
Roelof
Edit1 :
I tried this:
% Displays the output of siblings(X,Y) and takes care that
% there are no duplicates.
display_siblings(Person) :-
findall(Person-Y, siblings(Person,Y), Sibs),
display_the_siblings(Sibs).
% Display a message if there are no siblings found.
display_the_siblings([]) :-
write('Er zijn geen zussen/broers bekend').
% Displays a message if one sibling is found.
display_the_siblings([X-Y]) :-
write('The enigste broer of zuster is '),
write(Y).
% Display a message if there are more then 1 siblings found.
display_the_siblings([[X-Y|X-Y]) :-
write('Alle zusterparen zijn : \n'),
But if I use recursion then when Sibs is one then the wrong predicate is used.
So the question is still what do I take as parameters to make the last predicate work.
I have in my ~/.plrc (the SWI-Prolog basic configuration file on Linux) this definition
setln(Pattern, Goal) :-
setof(Pattern, Goal, List), maplist(writeln, List).
that just allows a sorted display of solutions, in case I need it... for instance
?- setln(M, current_module(M)).
ansi_term
apply
arithmetic
base32
...
My prolog is kinda rusty, but in general you do this with recursion on the list using the [Head|Tail]. Something like:
display_answer([]) :- !.
display_answer( [Head|Tail] ) :-
print( Head ),
display_answer( Tail ).
Hope it helps. Have fun...

How do you translate DCGs into normal definite clauses in 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).

Resources