How many different functions are there from Bool to Bool? - functional-programming

Since this is (at least it seems to me) tightly related to programming, I'm asking here rather than on math or cs, but if you it think it best fits there or in another side, please just give your opinion.
At the end of Chapter 2 of Bartosz Milewski's Category Theory for Programmers, there's this question:
How many different functions are there from Bool to Bool? Can you implement them all?
This is my reasoning:
Bool has only two elements in it, True and False;
different refers to what the functions do if considered blackboxes, regardless of what happens within them (for instance, two functions coding the sum of two Ints as arg1 + arg2 and arg2 + arg1 respectively, would be the same function from Int to Int);
so the different functions are those going from one of the two Bools to another of the two Bools:
T to T
T to F
F to T
F to F
What functions do I need to make those in-out scenarii possible? Well, I think I need only two, for instance the identity function, which would allow 1 and 4, and the negation, which would allow 2 and 3.
Is my reasoning correct?

the different functions are those going from one of the two Bools to another of the two Bools
No. A function does map every value from its domain to one value from its codomain. You need to consider all possible combinations of mappings. For this, it might make sense to look at the function as a relation, and list them all:
f -> f, t -> f
f -> f, t -> t
f -> t, t -> f
f -> t, t -> t
These correspond to the 4 functions
x => f (constant false)
x => x (identity)
x => not(x) (negation)
x => t (constant true)

The fact that you asked on Programming, rather than math or CS, is important.
On Math, they'd tell you there are four such functions, listed by the other answers.
On CS, they'd tell you there are 27: one for each of three possible inputs T F and ⊥ to each of three possible outputs T F and ⊥.
Here in programming, I can tell you there are eleven:
(T->T, F->F, ⊥->⊥) identity
(T->F, F->T, ⊥->⊥) not
(T->T, F->T, ⊥->T) lazy constant true
(T->F, F->F, ⊥->F) lazy constant false
(T->T, F->T, ⊥->⊥) strict constant true
(T->F, F->F, ⊥->⊥) strict constant false
(T->⊥, F->F, ⊥->⊥) identity fail on true
(T->T, F->⊥, ⊥->⊥) identity fail on false
(T->⊥, F->T, ⊥->⊥) not fail on true
(T->F, F->⊥, ⊥->⊥) not fail on false
(T->⊥, F->⊥, ⊥->⊥) fail
(This answer is quite tongue-in-cheek: I think in reality most scholarly CS types would say either 4 or 11.)

There are four functions:
1
false -> false
true -> false
2
false -> false
true -> true
3
false -> true
true -> false
4
false -> true
true -> true
Explanation
Your reasoning is mostly correct. The functions are blackboxes, we view them as values. Since the input is a boolean and has two possible values and the function might have two separate values, basically the number if 2^2 = 4

Related

Non-total functions are treated as constants at the type level?

In Type-Driven Development with Idris, ch 6, he says
Type-level functions exist at compile time only ...
Only functions that are total will be evaluated at the type level. A function that isn't total may not terminate, or may not cover all possible inputs. Therefore, to ensure that type-checking itself terminates, functions that are not total are treated as constants at the type level, and don't evaluate further.
I'm having difficulty understanding what the second bullet point means.
How could the type checker claim the code type checks if there's a function that isn't total in its signature? Wouldn't there by definition be some inputs for which the type isn't defined?
When he says constant, does he mean in the same sense as in the docs, like
one: Nat
one = 1
is a constant? If so, how could that enable the type checker to complete its job?
If a type-level function exists at compile time only, does it ever get evaluated if it's not total? If not, what purpose does it serve?
Partial type-level functions are treated as constants in the Skolem sense: invocations of a partial function f remain f with no further meaning.
Let's see an example. Here f is a partial predecessor function:
f : Nat -> Nat
f (S x) = x
If we then try to use it in a type, it will not reduce, even though f 3 would reduce to 2:
bad : f 3 = 2
bad = Refl
When checking right hand side of bad with expected type
f 3 = 2
Type mismatch between
2 = 2 (Type of Refl)
and
f 3 = 2 (Expected type)
So f is an atomic constant here, standing only for itself. Of course, because it does stand for itself, the following still typechecks:
good : f 3 = f 3
good = Refl

Why do the expressions isTRUE(3) and isTRUE(NA) evaluate to false in R?

Since all values other than 0 are taken as true in R, isTRUE(3) should logically evaluate to True but it doesn't. Why so?
Also, I would like to know the reason behind isTRUE(NA) being evaluated to false.
Straight from the documentation (try ?isTRUE)
isTRUE(x) is an abbreviation of identical(TRUE, x), and so is true if and only if x is a length-one logical vector whose only element is TRUE and which has no attributes (not even names).
It's not just doing a check on value, it's doing a check to ensure it is a logical value.
I know in computer science often 0 is false and anything non-zero is true, but R approaches things from a statistics point of view, not a computer science point of view, so it's a bit stricter about the definition.
Saying this, you'll notice this if statement evaluates the way you would imagine
if(3){print("yay")}else{print("boo")}
It's just the way R going about evaluation. The function isTRUE is just more specific.
Also note these behaviours
FALSE == 0 is true
TRUE == 1 is true
TRUE == 3 is false
So R will treat 0 and 1 as false and true respectively when perform these sorts of evaluations.
I'm not sure what your planned implementation was (if there was any) but it's probably better trying to be precise about boolean logic in R, or test things beforehand.
As for NA, more strange behaviour.
TRUE & NA equates to NA
TRUE | NA equates to TRUE
In these cases R forces NA to a logical type, since anything or'd with TRUE is a TRUE, it can equate that. But the value would change depending on the second term in an and operation, so it returns NA.
As for your particular case, again isTRUE(NA) is equated as false because NA is not a length-one logical vector whose only element is TRUE.
Because this function bypass R's automatic conversion rules and check that x is literally TRUE or FALSE.

working with powers in ocaml

I am trying to write a recursive function that will return true if second number is power of first number.
For example:
find_power 3 9 will return true
find_power 2 9 will return false because the power of 2 is 8 not 9
This is what I have tried but I need a recursive solution
let rec find_power first second =
if (second mod first = 0)
return true
else
false ;;
A recursive function has the following rough form
let rec myfun a b =
if answer is obvious then
obvious_answer
else
let (a', b') = smaller_example_of_same_problem a b in
myfun a' b'
In your case, I'd say the answer is obvious if the second number is not a multiple of the first or if it's 1. That is essentially all your code is doing now, it's testing the obvious part. (Except you're not handling the 0th power, i.e., 1.)
So, you need to figure out how to make a smaller example of the same problem. You know (by hypothesis) that the second number is a multiple of the first one. And you know that x * a is a power of a if and only if x is a power of a. Since x is smaller than x * a, this is a smaller example of the same problem.
This approach doesn't work particularly well in some edge cases, like when the first number is 1 (since x is not smaller than x * 1). You can probably handle them separately.

Count number of true variables in a boolean expression

How do I write a boolean expression that is able to verify the amount of variables that are set to true? I will provide a simplified example of the problem I am trying to solve. Please read the whole question before answering because the actual question is at the very end.
Declarations:
3 boolean variables: a b c
int expected = 2
How do I write a boolean expression that is able to verify that out of the 3 boolean variables there are exactly 2 set to true. Something along the lines of problem = (a + b + c) == 2 where problem would be true if exactly 2 of the boolean variables are set to true.
That is the simplified version of the problem, with exactly 3 boolean variables and expected = 2 we can solve the problem with problem = (a & b) | (b & c) | (c & a)
My question however is, how do we solve this using n number of boolean variables, and a varying amount for the expected variable using first order logic including logical connectives, predicates, and quantifiers.
I want to stress that I am not looking for actual code from any specific language but just a proposition/predicate expression.
If you assume that false resolves to 0 and true to 1, then you could do:
ans = ((a + b + c + ... + z) == expected)
Where a..z are boolean variables (possibly results from other expressions' evaluations) and expected is the number of true conditions that you want.

how can i use a logical function to represent continuous parameters?

I am trying to use an "implication" function that take two parameters f(A,B)= A -> B. In boolean algebra this kind of functions (eg. conjunction , disjunction ...) are used with only boolean parameters (true or false , 1 or 0).Imagine that these parameters take continuous values (between 0 and 1) and that the result function (A,B) will take also values between 0 and 1 instead of true or false.
for example :
when A increases(is near 1) and B increases(is near 1) f(A,B) increases(near 1)
when A increases and B decreases f(A,B) decreases
when A decreases and B increases f(A,B) increases
when A decreases and B decreases f(A,B) increases
How can i parse the implication function into a mathematical function that handle my continues values ?
Found it. The problem can be solved using the Fuzzy logic, which is a form of many-valued logic in which the truth values of variables may be any real number between 0 and 1. By contrast, in Boolean logic, the truth values of variables may only be 0 or 1. Fuzzy logic has been extended to handle the concept of partial truth, where the truth value may range between completely true and completely false. So may boolean implication function would be transformed to a fuzzy implication function, see here for more details.

Resources