Does MiniKanren have the "not" operator?
For example, how would one represent Prolog's
a :- b, not(c)
a is true if b is true and c is not (Prolog uses negation as failure, i.e. not(c) is considered proven if c can not be proven)
Prolog's not also works with non-ground expressions, e.g.
a(X, d(Y)) :- b(d(X), d(Y)), not(c(d(X)))
According to https://github.com/zhjhxxxjh/ykanren the answer is no.
There is no not operator in minikanren, but you can achieve something similar with conda:
(defmacro not
"fail if the given goal succeeds, use with extreme caution"
[goal]
`(conda
[~goal fail]
[succeed]))
See my similar question on Google Groups
Related
I'm trying to define some operators that add the operators with the arguments and the lone arguments to a list.
So far I've defined the two operators I'm gonna use, which are OR and NEGATION, but i don't know how to specify the actions they have to do next, which are creating the lists and add the operators and arguments to it.
:- op(400,fx,neg).
:- op(500,xfx,or).
After that I'm not certain of how to add the operators and arguments to a list and make a union of all the lists.
According to the union instruction in the manual it would be something like this:
neg(X,[]) :- union([X],[neg(X)],[]).
or(X,Y,[]) :- union([X],[or(X,Y)],[]).
or(X,Y,[]) :- union([Y],[or(X,Y)],[]).
Which doesn't send any errors, but how do I make the union of all the lists and how do I specify that any lower case letter can be used for input.
An example of an imput would be:
neg(a or b).
And the expected output:
[neg(a or b), a or b, a, b]
You're running into an interesting global thing about Prolog that operators really bring to the surface, which is that operators are just another way of constructing terms.
These operator definitions of yours enable you to create terms, such as:
?- X = neg a or b.
X = neg a or b.
Endowing these terms with meaning, on the other hand, will require you to create another predicate. This is because terms in Prolog are not expressions that reduce on their own—this is partly why you need to use is/2 to reduce an arithmetic expression to a value. Even things that are purely arithmetic are just terms in Prolog:
?- X = 16*3 + 4.
X = 16*3+4.
This is not some special behavior of =/2 in Prolog. This is how terms are made. Reducing the value requires deploying another predicate:
?- X is 16*3+4.
X = 52.
So what you appear to have done is assumed that your neg operator has induced a two-argument predicate for reducing it and that your or operator has induced a three argument predicate for reducing it. Actually neither of these things has happened, all that your operator declarations do is allow you to create terms like the one above, neg a or b. So you still need to create a separate predicate for evaluating them, which is where your semantics enter the picture. So let's implement an eval/2 predicate that converts your term into the result value you want:
eval(neg X, [neg X|Result]) :-
eval(X, Result).
eval(X or Y, [X or Y|Result]) :-
eval(X, R1),
eval(Y, R2),
append(R1, R2, Result).
eval(X, [X]) :- atomic(X).
The key idea here is to match what your operators give you and peel one layer off at a time, recursively calling the rest. Our base case is "atomic values" which is to say atoms like a.
This gives us what you're looking for:
?- eval(neg (a or b), R).
R = [neg (a or b), a or b, a, b]
Note that is/2 is an operator. You could also define an operator which "does work" by declaring the operator and then supplying rules for their application. That won't help you in this case, because your examples for neg and or require you to retain structure rather than discard it. is/2, on the other hand, assumes the structure exists on the right argument and reduces it to a value for the left. You could do something similar, by say making eval/2 an operator, in which case the operator is used on the left side of the :-, like so:
[Neg X|R] eval (neg X) :- R eval X.
However, I find this kind of hard to handle and would definitely avoid it unless it ushered in more clarity.
By the way, you will most likely want to replace xfx in your op/3 call with either xfy or yfx, since constructions like a or b or c will not work with xfx due to an operator priority clash. With xfy, it will be parsed as a or (b or c) and with yfx it will be parsed as (a or b) or c which is probably more helpful. And also, if you intend always to parenthesize what you use neg with, then you do not need to declare an operator for it—the purpose of a unary operator is just to allow you to skip the parens (and control how much of what follows is consumed by it.)
Hope this helps!
Here is a first observation:
?- is_list([]), is_list([_,_,_]).
true.
Here is another observation:
?- [] = _, [_,_,_] = _.
true.
Therefore, why would is_list/1 be implemented such that
?- is_list(_).
false.
or
?- is_list([_|_]).
false.
when _ can clearly be unified with a list? Wouldn't that be logically sounder that it be true?
In SWI-Prolog's documentation for is_list/1, a note says:
In versions before 5.0.1, is_list/1 just checked for [] or [_|_] and proper_list/1 had the role of the current is_list/1. The current definition conforms to the de facto standard.
Why is that the de facto standard?
As you correctly observe, is_list/1 is unsound, or rather incomplete, because it incorrectly says that there are no solutions whatsoever when the most general query is posed.
?- is_list(Ls).
false.
No list exists? Come on!
This unfortunate trait is shared by all hereditary type checking predicates like atom/1, integer/1 etc., whose incorrectness was obvious already when these predicates were conceived yet pushed through after labeling those who correctly opposed their suggested semantics as "purists" (which, at that time, lacked the complimentary character the word has since acquired).
Cases like:
?- is_list(Ls), Ls = [].
false.
?- Ls = [], is_list(Ls).
Ls = [].
clearly illustrate that something is fundamentally broken from a logical point of view with such non-monotonic tests. "Prolog's (,)/2 is not logical conjunction", yes, if you use illogical predicates in the first place in your code. Otherwise, (,)/2 is always a logical conjunction of goals.
A clean and logically correct way out is to throw instantiation errors in cases that cannot yet be determined.
library(error) and in particular must_be/2 go into a sound direction after the incorrectness of inherited illogical predicates has become unbearable even for casual users of Prolog:
?- must_be(list, X).
Arguments are not sufficiently instantiated
?- must_be(list, [_|_]).
Arguments are not sufficiently instantiated
?- must_be(list, [a,b,c]).
true.
must_be/2 is easy to use and a good first step towards more correct logic programs. Other constructs also appear on the horizon, and I hope others comment on the current status.
And now for the actual wording: Putting aside the fundamental problem outlined above, the contention alluded to in the SWI documentation is whether checking the outermost functor suffices to regard a term as a list, or whether the list must actually conform to the inductive definition of a list, which is:
the atom [] is a list.
if Ls is a list, then '.'(_, Ls) is a list.
Note that in recent SWI versions, [] is not even an atom, so it again breaks with this notion.
I have the following regex
(1*)+(1*0)(ε+11*0)*(11*)
If minimized, it should be
(1+01)*
But I cannot understand the minimization, could somebody explain it?
First off, for other people watching this, this is traditional formal Computer science regular expressions, not the regex languages used in most programming languages. In programming language regex terms, the two expressions would be 1*|1*0(|11*0)*11* and (1|01)*.
Now, to the problem:
The initial expression has 1* at the front and back of the expression in both of the top-level alternatives. So we can rewrite it first as:
(1*)(ε+0(ε+11*0)*1)(1*)
Now, in general, (ε+x)* for any regular expression x is just x*. So that's:
(1*)(ε+0(11*0)*1)(1*)
Now, also x* is the same as ε+xx*, so we can expand that inner bit out:
(1*)(ε+0(ε+(11*0)(11*0)*)1)(1*)
And now apply a(x+y)b => axb+ayb:
(1*)(ε+01+0(11*0)(11*0)*1)(1*)
Now, apply (xy)*x => x(yx)*:
(1*)(ε+01+0(11*0)1(1*01)*)(1*)
And rearrange the parens:
(1*)(ε+01+(01)(1*)(01)(1*(01))*)(1*)
And factor out a common prefix:
(1*)(ε+(01)(ε+(1*(01))(1*(01))*))(1*)
Using an expansion we had before, but in reverse:
(1*)(ε+(01)(1*(01))*)(1*)
Now bring that left 1* in:
((1*)+(1*)(01)(1*(01))*)(1*)
Since 1* is the same as ε+1*, we can write this as:
((ε+1*)+(1*)(01)(1*(01))*)(1*)
Rearranging alternatives:
(1*+(ε+(1*)(01)(1*(01))*))(1*)
Applying that ε+xx* <=> x* equivalence again:
(1*+(1*(01))*)(1*)
Now, x*+(x*y)* can be shown equivalent to (x+y)* - applying that here gives:
(1+01)*(1*)
And now we just apply (x+y)*x* => (x+y)*, and we're done.
(1+01)*
Okay, trying to work out a simpler derivation. First off, I need you to accept these identities, where x, y, a, and b are arbitrary regular expressions:
(ab)*a <=> a(ba)*
xa+ya <=> (x+y)a
ε+xx* <=> x*
a*(ba*)* <=> (a+b)*
As an aside, the last identity is often useful in constructing regexes that efficiently match grammars like strings with backslash escapes, where a naive approach might be ([^\\"]|\\.)*, but it's much more efficient in most regex matching libraries to use [^\\"]*(\\.[^\\"]*)*. Anyway, to the problem:
(1*)+(1*0)(ε+11*0)*(11*)
Well, (ε+x)* is still the same as x*, so let's do that first:
(1*)+(1*0)(11*0)*(11*)
Now apply identity 2 and pull the 1* out to the right:
(ε+(1*0)(11*0)*1)(1*)
Now, identity 1:
(ε+(1*0)1(1*01)*)(1*)
That's now ready for identity 3:
(1*01)*(1*)
Identity 1 again gives us:
1*((01)1*)*
And now identity 4 gives us the desired result:
(1+01)*
I have recently started learning prolog, and facing a problem with this question:
Define a rule to determine if a list contains a given member.
I searched all over stack overflow to get some links to understand this problem better and write solutions for it but couldn't find anything. Could anyone of you advice to solve this particular problem?
My Approach:
Iterative over the list and see if your member matches with head:
on(Item,[Item|Rest]). /* is my target item on the list */
on(Item,[DisregardHead|Tail]):-
on(Item,Tail).
Do you think my approach is correct?
What you have is indeed a "correct" implementation. The standard name for a predicate that does that is member/2, and is available (under that name) in any Prolog, and should be quite easy to find once you know its name.
Some things to note however. First, with the classical definition (this is exactly as in "The Art of Prolog" by Sterling and Shapiro, p. 58, and identical to yours):
member_classic(X, [X|Xs]).
member_classic(X, [Y|Ys]) :-
member_classic(X, Ys).
If you try to compile this, you will get singleton errors. This is because you have named variables that appear only once in their scope: the Xs in the first clause and the Y in the second. This aside, here is what the program does:
?- member_classic(c, [a,b,c,x]).
true ;
false.
?- member_classic(c, [c]).
true ;
false.
?- member_classic(X, [a,b,c]).
X = a ;
X = b ;
X = c ;
false.
In other words, with this definition, Prolog will leave behind a choice point even when it is quite obvious that there could not be further solutions (because it is at the end of the list). One way to avoid this is to use a technique called "lagging", as demonstrated by the SWI-Prolog library implementation of member/2.
And another thing: with your current problem statement, it might be that this is considered undesirable behaviour:
?- member_classic(a, [a,a,a]).
true ;
true ;
true ;
false.
There is another predicate usually called member_check/2 or memberchk/2 which does exactly what you have written, namely, succeeds or fails exactly once:
?- memberchk(a, [a,a,a]).
true.
?- memberchk(a, [x,y,z]).
false.
It has, however, the following behaviour when the first argument is a variable that might be undesirable:
?- memberchk(X, [a,b,c]).
X = a. % no more solutions!
There are valid uses for both member/2 and memberchk/2 IMHO (but interestingly enough, some people might argue otherwise).
Yes, your solution is correct and works in all directions. Nice!
Notes:
Your solution is in fact more general than what the task asks for. This is a good thing! The task, in my view, is badly worded. First of all, the first clause is not a rule, but a fact. It would have been better to formulate the task like: "Write a Prolog program that is true if a term occurs in a list." This leaves open other use cases that a good solution will also automatically solve, such as generating solutions.
This common predicate is widely known as member/2. Just like your solution, it also works in all directions. Try for example ?- member(E, Ls).
The name for the predicate could be better. A good naming convention for Prolog makes clear what each argument means. Consider for example: element_list/2, and start from there.
Given the following:
&row->count
Would &(row->count) be evaluated or (&row)->count be evaluated in C++?
EDIT: Here's a great link for C++ precedence.
As far as precedence rules go, I've always liked the one put forth by Steve Oualline in "Practical C":
There are fifteen precedence rules in
C (&& comes before || comes before
?:). The practical programmer reduces
these to two:
1) Multiplication and division come
before addition and subtraction.
2) Put parentheses around everything
else.
&(row->count)
This is already asked. But here is a link.
Edit:
Ok this question is very similar. And possibly there is an other one.
May I suggest that you resolve such questions using a test programme? That has the advantage that you will know for sure that the answer is correct for your implementation, and you are not exposed to the risk of badly answered questions.
C operator precendence is explained here
As per the table, -> is higher priority than the & operator, so it's &(row->count)
&(row->count)
-> has a higher priority than & (address of). So your expression would be evalutated as &(row->count)