Boolean condition affected by inputs - boolean

I was testing what happens when I pass random values to an arbitrary boolean condition in Python. I ran a loop 10 times and declared each time a random choice of True or False to A and B. I then saw if the condition returned True or False and outputted the values of A and B.
for i in range(10):
A = random.choice([True, False])
B = random.choice([True, False])
if (A and (A or B)) == True:
print("Pass:")
print("A: {} B: {}".format(A, B))
else:
print("Fail:")
print("A: {} B: {}".format(A, B))
Outputs:
Pass: Fail: Pass: Pass:
A: True B: True A: False B: True A: True B: False A: True B: False
Pass: Pass: Pass:
A: True B: True A: True B: False A: True B: True
Pass: Pass: Fail:
A: True B: True A: True B: True A: False B: False
The boolean condition I chose was sort of randomly written (meaning no particular reason for that one), but I found a sort of pattern in the outputs.
The value of B in all the Passes was different (same for the Fails), but the value of A was always True in the Passes and False in the Fails. Remember that a Pass is the result of the condition being True, hence it seems the condition happens to return a boolean value which is the same as the input A.
Since I found this particular condition odd, I ran another test. This time I checked if this boolean expression always gave the same as the initial input of A. I also ran it 20 times to get more random values for the inputs.
for i in range(20):
A = random.choice([True, False])
B = random.choice([True, False])
if (A and (A or B)) == A:
print("Pass")
else:
print("Fail")
Output:
Pass
Pass
Pass
. . .
Pass
Pass
Pass
I have simplified the output, but when I ran the code, it gave all 20 passes and the same when the code was run a few times.
My question is why does this condition, I guess "simplify", to just the input A? And can boolean expressions be "simplified" (as in this situation the whole expression renders pointless if the result is always just A) in order to shorten conditions?

This is a trivial result in symbolic logic.
If A is true, then your expression evaluates as follows:
True and (True or B)
True or B
True

This field of mathematics is called Boolean algebra. Your specific example is the Absorption Law, eg form 10a or "X • (X + Y) = X" here:
https://www.mi.mun.ca/users/cchaulk/misc/boolean.htm
(In Boolean algebra, "and" is sometimes written as • and "or" is sometimes written as +. This makes analogies to integer algebra more obvious, eg X + 0 = X and X • 0 = 0.)
Your larger question of "can boolean expressions be simplified" depends on the expression! Often they can, but certain forms are fully simplified. A full discussion is beyond the scope of Stack Overflow - there are various web resources or online classes. It's not particularly difficult but it's a bigger subject than one answer can cover.

Related

How does the contains method in a binary search tree return false when no conditions are satisfied?

I have a method for a class that implements a set for integers using the binary search tree data structure. One of the methods is a contains method that returns true if a set contains a given integer
Both implementation of the method below is correct, but I'm trying to understand why doing it this way:
def contains(x: Int): Boolean =
if (x < elem) left.contains(x)
else if (elem < x) right.contains(x)
else true
is sufficient compared to being exhaustive and doing it this way:
def contains(x: Int): Boolean =
if (x < elem) left.contains(x)
else if (elem < x) right.contains(x)
else if (elem == x) true
else false
What is the intuitive reason for the method in the first approach returning false if the integer does not belong in the set?
You are right to be suspicious because it appears that the only way to end recursion is by returning true.
However I think you will find that the tree has different classes for node elements and leaf elements. What you have shown is the contains method for a node. The contains method for a leaf will just returns false, ending the recursion.
Alternatively, it may be the left and right are Option[Node]. In this case you will get false if the Option is None because None.contains(_) is always false.
A binary search tree is always constructed such that left branch has elements that are smaller than the node value - elem, and right branch elems are all larger than elem.
Following this logic if your x is neither smaller, nor larger than elem you are left with only possibility: it's equal to the elem. Hence, no need to test for equality, and the second implementation's: else false will always be a dead branch.
Think about it this way: if you take two numbers and neither of them is smaller or bigger than the other, then they must be the same number.

An algorithm that determines if a function f from the finite set A to the finite set B is an onto function.

How can I write an algorithm that determines if a function f from the finite set A to the finite set B is an onto function.
This is what I have so far:
A: array ( members of set A )
B: array ( members of set B )
Mapped: associative array of Boolean variables.
for each b in B:
Mapped[b] = false
for each a in A:
Mapped[f(a)] = true
Onto = true;
for each b in B:
Onto = Onto AND Mapped[b]
return Onto
Is this correct?
Yeah, that'll work. A potentially easier approach would be
for each a in A:
remove f(a) from B
return (is B empty?)
And then of course you should sort B first, so you can remove more quickly.

I need to check in scala if a number is present in a list /set of numbers and retrieve boolean as a result

Let y be a set or list of numbers, e.g List(1,2,3,4) and suppose val x=1 so i need to check whether x is present in y collection. In this case boolean result as true is expected, and suppose val x=7 where the result should be false.
Just use contains to check whether value exists or not.
list.contains(value)
For sets consider
val s = Set(1,2,3,4)
s(1)
Boolean = true
a short for set inclusion, implemented by
s.apply(1)
Boolean = true
Moreover,
s(7)
Boolean = false
Valid for lists and sets alike (in addition to contains) is exists, for example,
s.exists(_ == 1)
Boolean = true
s.exists(_ == 7)
Boolean = false

Scala forall example?

I tried Google search and could not find a decent forall example. What does it do? Why does it take a boolean function?
Please point me to a reference (except the Scaladoc).
The forall method takes a function p that returns a Boolean. The semantics of forall says: return true if for every x in the collection, p(x) is true.
So:
List(1,2,3).forall(x => x < 3)
means: true if 1, 2, and 3 are less than 3, false otherwise. In this case, it will evaluate to false since it is not the case all elements are less than 3: 3 is not less than 3.
There is a similar method exists that returns true if there is at least one element x in the collection such that p(x) is true.
So:
List(1,2,3).exists(x => x < 3)
means: true if at least one of 1, 2, and 3 is less than 3, false otherwise. In this case, it will evaluate to true since it is the case some element is less than 3: e.g. 1 is less than 3.
A quick example of how you can play with this function using a Scala script.
create a myScript.scala file with
println(args.forall(p => (p.equals("a"))))
and call it with
scala myScript.scala a a a // true
scala myScript.scala a b c // false
Scala's forall is also a great tool to do something like applying logical and to a list of boolean values with the early exist:
val evalResults: List[Boolean] = List(evaluateFunc1(), evaluateFunc2(), evaluateFunc3(), evaluateFunc4(), evaluateFunc5())
evalResults.forall(result => result == true)

Scala set function

In Stanford Scala course I've come across the following assignment:
Exercise 1 – Sets as Functions:
In this exercise we will represent sets as functions from Ints to Booleans:
type Set = Int => Boolean
a) Write a function "set" that takes an Int parameter and returns a Set containing that Int.
b) Write a function "contains" that takes a Set and an Int as parameters and returns true if the Int is in the Set and false otherwise.
c) Write the functions "union", "intersect", and "minus" that take two Sets as parameters and return a Set.
d) Can you write a function "subset" which takes two Sets as parameters and returns true if the first is a subset of the second and false otherwise?
Solutions to the a, b and c are fairly trivial:
def set(i: Int): Set = n => n == i
def contains(s: Set, i: Int) = s(i)
def union(a: Set, b: Set): Set = i => a(i) || b(i)
def intersect(a: Set, b: Set): Set = i => a(i) && b(i)
def minus(a: Set, b: Set): Set = i => a(i) && !b(i)
But is there any elegant solution for d?
Of course, strictly speaking, the answer to d is "yes", as I can write something like:
def subset(a: Set, b: Set) = Int.MinValue to Int.MaxValue filter(a) forall(b)
but that's probably not the right way.
I don't think it's possible without iterating through all the integers. For a pseudo-proof, look at the desired type:
def subset: (a: Set, b: Set): Boolean
Somehow, we've got to produce a Boolean when all we have to work with are sets (a, b) of type Int => Boolean, and integer equality (Int, Int) => Boolean. From these primitives, the only way to get a Boolean value is to start with Int values. Since we don't have any specific Int's in our hands, the only option is to iterate through all of them.
If we had a magical oracle, isEmpty: Set => Boolean, the story would be different.
A final option is to encode "false" as the empty set and "true" as anything else, thus changing the desired type to:
def subset: (a: Set, b: Set): Set
With this encoding, logical "or" corresponds to the set union operation, but I don't know that logical "and" or "not" can be defined easily.
We have
Set A =
Returns the intersection of the two given sets,
the set of all elements that are both in `s` and `t`.
Set B =
Returns the subset of `s` for which `p` holds.
Isn't Set A is equivalent to Set B
def filter(s: Set, p: Int => Boolean): Set = intersect(s, p)
I agree with Kipton Barros, you would have to check all values for Ints since you want to prove that forall x, a(x) implies b(x).
Regarding the optimization of it, I'd probably write:
def subset(a: Set, b: Set) = Int.MinValue to Int.MaxValue exists(i => !a(i) || b(i))
since !a(i) || b(i) is equivalent to a(i) implies b(i)
Later on in the Coursera exercises bounded sets are introduced and then forall() and exists() as universal and existential quantifiers over the bounds. subset() was not in the exercises but is similar to forall. Here is my version of subset():
// subset(s,p) tests if p is a subset of p returning true or false
def subset(s: Set, p: Set): Boolean = {
def iter(a: Int): Boolean = {
if (a > bound) { true
} else if (contains(p, a)) {
if (contains(s, a)) iter(a + 1) else false
} else iter(a+1)
}
iter(-bound)
}
Here is another version of it using contains function:
def union(s: Set, t: Set): Set = x => contains(s,x) || contains(t,x)
def intersect(s: Set, t: Set): Set = x => contains(s,x) && contains(t,x)
def diff(s: Set, t: Set): Set = x => contains(s,x) && !contains(t,x)
def filter(s: Set, p: Int => Boolean): Set = x => contains(s, x) && p(x)
If there are two sets A and B, then A intersect B is a subset of A and B. Mathematically proven: A ∩ B ⊆ A and A ∩ B ⊆ B. Function can be written like this:
def filter(s: Set, p: Int => Boolean): Set = x => s(x) && p(x)
Or
def intersect(s: Set, t: Set): Set = x => s(x) && t(x)
def filter(s: Set, p: Int => Boolean): Set = intersect(s,p)