Why does `x =! 5` return false? - ruby

I've been studying operator precedence and it was explained to me that x =! 5 returns false. I can't seem to explain why to myself again. I know =! isn't a operator so then x and 5 remain. So does that mean Ruby doesn't know what to do? If so ruby should return an error because x can have no value? Does Ruby stop at the operator and then assign a value of false to x?
x =! 5
=> false

This is because x =! 5 is being interpreted as x = (!5) (! has higer precedence than =). In Ruby every object is true except nil and false. 5 has truthy value which you are negating using the operator !. So false as result is being assigned to the local variable x.
! Called Logical NOT Operator - is used to reverse the logical state of its operand. If a condition is true, then Logical NOT operator will make false.

There's no such a thing as =! operator in Ruby. != is what checks for not equal.
So basically, when the parser is looking at the code and find an =, it looks for other operators that start with = such as ==. If it finds no match, which is the case here ( =! ), it considers the expression as an assignment, and assigns the right hand side to the left hand side. In this case, the right hand side of the = is ! 5, which is equal to false.

Related

Prolog: what is difference between, for example, X is 3 and 3 is X?

three(X) :- 3 is X.
three2(X) :- X is 3.
Requests three(3), three(5) and three2(3), three2(5) respectively have the same answers.
But three2(X) has answer 3, while three(X) has answer "Arguments are not sufficiently instantiated".
If there's enough data to solve that three(3) is true and three(5) is false, why there's not enough data to find that X is equals 3 when we request for the value of X?
That's because is/2 is the numeric expression evaluator of Prolog. Everything on the Right Hand Side of is/2 must be fully instantiated so that the expression can then be evaluated to a number (possibility missed: evaluate to something else than numbers). The result is then unified with the Left Hand Side of is/2. This succeeds if the LHS is an unbound variable or the same as the result obtained.
In your case, you can make the predicate three/1 symmetric by just unifying, as there is really nothing to evaluate:
three_sym(X) :- 3 = X.
Succeeds with 3 and outputs the answer X = 3 for an unbound X.

Is nonexistence queriable in Datalog?

Suppose I've defined a few values for a function:
+(value[1] == "cats")
+(value[2] == "mice")
Is it possible to define a function like the following?
(undefined[X] == False) <= (value[X] == Y)
(undefined[X] == True) <= (value[X] does not exist)
My guess is that it can't, for two reasons:
(1) Queries are guaranteed to terminate in Datalog, and you could query for undefined[X] == True.
(2) According to Wikipedia, one of the ways Datalog differs from Prolog is that Datalog "requires that every variable appearing in a negative literal in the body of a clause also appears in some positive literal in the body of the clause".
But I'm not sure, because the terms involved ("terminate", "literal", "negative") have so many uses. (For instance: Does negative literal mean f[X] == not Y or does it mean not (f[X] == Y)? Does termination mean that it can evaluate a single expression like undefined[3] == True, or does it mean it would have found all X for which undefined[X] == True?)
Here another definition of "safe".
A safety condition says that every variable in the body of a rule must occur in at least one positive (i.e., not negated)
atom.
Source: Datalog and Recursive Query Processing
And an atom (or goal) is a predicate symbol (function) along with a list of terms as arguments. (Note that “term” and “atom” are used differently here than they are in Prolog.)
The safety problem is to decide whether the result of a given Datalog program can be guaranteed to be finite even when some source relations are infinite.
For example, the following rule is not safe because the Y variable appears only in a negative atom (i.e. not predicate2(Z,Y)).
rule(X,Y) :- predicate1(X,Z), not predicate2(Z,Y) .
To meet the condition of safety the Y variable should appear in a positive predicate too:
rule(X,Y) :- predicate1(X,Z), not predicate2(Z,Y), predicate3(Y) .

Prolog: why is true == not(not(true)) -> false?

Obviously true = not(not(true)) has to be false, because = tries to unify the atom true with the term not(not(true)) (without evaluating the term), which is false, since the terms are not identical.
However, I thought == really compares whatever is evaluated. Thus, I thought true == not(not(true)) should evaluate to true == true, just like (for arithmetic operators) 4 =:= 2 + 2 would evaluate to 4 =:= 4 and return true.
...but this is what I get in SWI-Prolog:
?- true == not(not(true)).
false.
What am I getting wrong?
(==)/2 does not compare whatever is evaluated. It does not evaluate its arguments. It only succeeds if the arguments are already instantiated to matching terms.
In prolog, not(not(true)) is a compound term, which is the term not/1 with a single argument, not(true), itself being a term not/1 of one argument consisting of the term true/0 which has no arguments. It doesn't have a value. It doesn't even get "executed" except in certain contexts. In Prolog, the predicate not/1 succeeds if it's argument fails, and it fails if its argument succeeds. This isn't the value or functional result, but a behavior. This is assuming that it appears in a context such as the following:
not(not(true)),
write('This will be written out because not(not(true)) succeeded'), nl.
The expression true == not(not(true)) in Prolog is a compound term, equivalent to:
'=='(true, not(not(true)))
In this context, not(not(true)) is not evaluated. Prolog will first exercise the (==)/2 equivalence operator, which succeeds if its arguments are instantiated to the same term. Are the terms true and not(not(true)) in Prolog the same (or equivalent)? No they are not. One is simple term with no arguments (true/0). The other is a compound term: a term with one argument that is itself a term with one argument. Thus the (==)/2 fails here.
Note that (=:=)/2 is quite different. It is an operator that compares results of arithmetic expressions. The arguments must be evaluable arithmetic expressions and (=:=)/2 will succeed if they evaluate to the same result, and it will fail if they do not.

Understanding precedence of assignment and logical operator in Ruby

I can't understand precedence of Ruby operators in a following example:
x = 1 && y = 2
Since && has higher precedence than =, my understanding is that similarly to + and * operators:
1 + 2 * 3 + 4
which is resolved as
1 + (2 * 3) + 4
it should be equal to:
x = (1 && y) = 2
However, all Ruby sources (including internal syntax parser Ripper) parse this as
x = (1 && (y = 2))
Why?
EDIT [08.01.2016]
Let's focus on a subexpression: 1 && y = 2
According to precedence rules, we should try to parse it as:
(1 && y) = 2
which doesn't make sense because = requires a specific LHS (variable, constant, [] array item etc). But since (1 && y) is a correct expression, how should the parser deal with it?
I've tried consulting with Ruby's parse.y, but it's so spaghetti-like that I can't understand specific rules for assignment.
Simple. Ruby only interprets it in a way that makes sense. = is assignment. In your expectation:
x = (1 && y) = 2
it does not make sense to assign something to 1 && y. You can only assign something to a variable or a constant.
And note that the purpose of the precedence rule is to disambiguate an otherwise ambiguous expression. If one way to interpret it does not make sense, then there is no need for disambiguation, and hence the precedence rule would not be in effect.
My understanding is that in the case of
x = 1 && y = 2
The logical AND is parsed first. The AND then is forced to evaluate its left side and its right side. In the evaluation the left side the first assignment occurs, and then in the evaluation of the right side the second does the same. It is for this reason that in the case of:
x = false && y = 2
"y" will never be assigned. The AND is hit, forcing the x assignment to evaluate, but never bothering to run the y assignment, as it is unnecessary for the AND to fulfill its purpose.
In other words, the parser is, again, simply to my understanding, smart enough to recognize that in running the AND the equation is split into a left and right side (equations), which are in turn evaluated according to the order of operation.

Difference between negation and inequality in Ruby?

What is the difference between if !variable == 10 {...} and if variable != 10 {...} in Ruby programming language? Of course this can be applied to all other languages. In first case are we just negating condition, and in second testing if variable is actually unequal to 10?
if variable != 10 is equivalent to unless variable == 10
while !variable is negating the variable, so first it's evaluated as an expression, then negated.
Example
variable = 5
variable != 10 # => true
!variable # => false (5 is evaluated to true, then negated)
!variable = 10 # => warning: found = in conditional, should be ==
To a large degree all programming languages, including Ruby, follow boolean algebra rules that state there's a number of ways to express the same condition.
x != y
!(x == y)
!!(x != y)
This also plays out in other domains, such as:
!x && !y
!(x || y)
As others have pointed out, be very careful when using the == comparator instead of the = assignment operator.

Resources