Disjunctions in DataLog - datalog

So how are OR conditions emulated/invoked in Datalog-land ?
This is probably the most basic question ask-able about DataLog but well hello this is my first attempt at using it ;)

Got it now: it's a strange syntax: disjunction is created by having multiple rules with the same name
myrecursive(X,Y) :- basecase1(Y,X).
myrecursive(X,Y) :- myrecursive(X,Z),myrecursive(Z,Y).
This means that a descendant may satisfy either of those two rules.

Related

Expanding DCGs in Prolog

I'm writing a code generator that converts definite clause grammars to other grammar notations. To do this, I need to expand a grammar rule:
:- initialization(main).
main :-
-->(example,A),writeln(A).
% this should print ([a],example1), but this is a runtime error
example --> [a],example1.
example1 --> [b].
But -->(example, A) doesn't expand the rule, even though -->/2 appears to be defined here. Is there another way to access the definitions of DCG grammar rules?
This is a guess of what your are expecting and why you are having a problem. It just bugs me because I know you are smart and should be able to connect the dots from the comments. (Comments were deleted when this was posted, but the OP did see them.)
This is very specific to SWI-Prolog.
When Prolog code is loaded it automatically goes through term expansion as noted in expand.pl.
Any clause with --> will get expanded based on the rules of dcg_translate_rule/2. So when you use listing/1 on the code after it is loaded, the clauses with --> have already been expanded. So AFAIK you can not see ([a],example1) which is the code before loading then term expansion, but example([a|A], B) :- example(A, B) which is the code after loading and term expansion.
The only way to get the code as you want would be to turn off the term expansion during loading, but then the code that should have been expanded will not and the code will not run.
You could also try and find the source for the loaded code but I also think that is not what you want to do.
Based on this I'm writing a code generator that converts definite clause grammars to other grammar notations. perhaps you need to replace the code for dcg_translate_rule/2 or some how intercept the code on loading and before the term expansion.
HTH
As for the error related to -->(example,A),writeln(A). that is because that is not a valid DCG clause.
As you wrote on the comments, if you want to convert DCGs into CHRs, you need to apply the conversion before the default expansion of DCGs into clauses. For example, assuming your code is saved to a grammars.pl file:
?- assertz(term_expansion((H --> B), '--->'(H,B))).
true.
?- assertz(goal_expansion((H --> B), '--->'(H,B))).
true.
?- [grammars].
[a],example1
true.

Different predicate in Prolog, don't work (always false)

I am learning Prolog for an university exam using SWI Prolog and I have some question about this simple program that implement the different predicate that say TRUE if two element are different (if they do not match) and say FALSE if they match.
This is the code:
different(X,X) :- !,
fail.
diferent(_,_).
The problem is that if I try to execute the following query in the Prolog shell I always obtain FALSE:
[debug] 10 ?- different(a,b).
false.
[debug] 11 ?- different(a,a).
false.
As you can see the first query have to say TRUE because a don't match with b
Why?
change diferent(_,_) to different(_,_). Ie it is a spelling error.
Your second predicate is not being examined as it does not match your query.
The program should be
different(X,X) :- !,fail.
different(_,_).
This "exercise" is pointless. Use prolog-dif!
IMO the only reasonable definition of different/2 is:
different(A,B) :- dif(A,B).
If you are using emacs for editing your prolog files (If not I strongly recommend you switching to it) I suggest you using hi-lock-mode. I will highlight in a pattern-like fashion all matches in the file whenever the cursor is over a word. It can save you hours of pain when you develop bigger projects.

how to assert an arithmetic relation in Prolog database

I'm using forward chaining algorithm proposed by Bratko. How can I enter arithmetic rules in prolog DB. For example I want to enter age is 35. In other words I want to enter the fact(age,35).
Thanks
Much depends on which Prolog you're using.
I think it's safe to presume the availability of assert/1, and the 'inverse' retract/1. The code you linked already uses assert/1.
Some Prolog requires the declaration of predicates to be manipulated via assert/retract:
:- dynamic fact/2.
...
assert(fact(age, 35)),
...
retract(fact(Kind, Value)),
write(Kind:Value),
...

Redefined AND operator in Prolog

I want to redefine AND operator in SWI-Prolog . But I do not know how to do it.
I tried the following definition:
a & b = b & a
However, it is reported as recursive and does not work.
Wish people give me suggestions.
Thanks in advance!
You could define an operator in SWI-Prolog using op/3, such as by adding the following to your program:
:- op(1000, xfy, user:(&)).
Note that the precedence level (1000) and type (xfy) are the same as that for the conjunction operator which is already defined in SWI-Prolog (i.e., see ','/2).
Then, once declared, you can define the semantics of & as follows:
'&'(A,B) :- A, B.
Together, these two definitions will permit you to use & in-line as a replacement for , to mean conjunction in the program which incorporates them.
You can "define" and as follows:
and(t,X,X) :- bool(X).
and(f,X,f) :- bool(X).
bool(t).
bool(f).
The third argument is the result of the conjunction of the first and the second argument.
Of course, this is just an exercise, but indeed it is hard to answer your question as it is not very clear what your question is all about.

Circular Prolog

I have the following prolog code:
equiAngularTriangle(T) :-
equiLateralTriangle(T).
equiLateralTriangle(T) :-
equiAngularTriangle(T).
Is there a way to keep the interpreter from asking the same question twice? For instance, if I ask equiAngularTriangle(t), then it's going to ask equiLateralTriangle(t), then ask equiLateralTriangle(t), but it should know not to pursue that last one again, because the same question is on the "query stack".
Is there an option or some special syntax that lets Prolog behave the way I want it to?
If the prolog implementation supports tabling or you are using XSB then you could use it and get the desired behaviour.
You could also add a state argument:
%State = [Checked_for_equiAngular, Checked_for_equiLateral]
equiAngularTriangle(T, [_,false]) :-
equiLateralTriangle(T, [true,true]).
equiLateralTriangle(T, [false,_]) :-
equiAngularTriangle(T, [true,true]).
of course you will need to modify the rest of the clauses.
The last (and best imo) option is to rewrite your predicates. I guess that your code will be similar to this example:
ang(T):-
foo(T).
ang(T):-
lat(T).
lat(T):-
bar(T).
lat(T):-
ang(T).
so you could simply write:
ang(T):-
foo(T).
ang(T):-
bar(T).
lat(T):-
ang(T).
normally you will use some wrapper predicates if instead of foo(T) you had foo1(T),foo2(T) etc
Try XSB Prolog. It implements tabling which will short-circuit evaluation like in your case. You need to tell it which predicates should be tabled, though.

Resources