Cases tactic in Lean does not create hypothesis - proof

When using the cases-tactic on an inductive data type, lean produces multiple cases, but does not create a hypothesis stating the assumption of the current case. For example:
inductive color | blue | red
theorem exmpl (c : color) : true :=
begin
cases c,
end
results in the following tactic state
case color.blue
⊢ true
case color.red
⊢ true
but does not create a separate hypothesis (like c = color.red) to work with. How would you get such a hypothesis?

Use cases h : c to get a new hypothesis h for each case. For more detail, see the documentation.
In the example, this would be
theorem exmpl (c : color) : true :=
begin
cases h : c,
end
resulting in
case color.blue
c: color
h: c = color.blue
⊢ true
case color.red
c: color
h: c = color.red
⊢ true

Related

Define a function inside of a proof in Lean

In Lean, we can define a function like this
def f (n : ℕ) : ℕ := n + 1
However, inside a proof this is no longer possible. The following code is invalid:
theorem exmpl (x : ℕ) : false :=
begin
def f (n : ℕ) : ℕ := n + 1,
end
I would assume that it is possible with have instead, but attempts like
theorem exmpl (x : ℕ) : false :=
begin
have f (n : ℕ) : n := n + 1,
have f : ℕ → ℕ := --some definition,
end
did not work for me. Is it possible to define a function inside of a proof in lean and how would you achive that?
(In the example above, it would be possible to define it before the proof, but you could also imagine a function like f (n : ℕ) : ℕ := n + x, which can only be defined after x is introduced)
Inside a tactic proof, you have the have and let tactics for new definitions. The have tactic immediately forgets everything but the type of the new definition, and it is generally used just for propositions. The let tactic in contrast remembers the value for the definition.
These tactics don't have the syntax for including arguments to the left of the colon, but you can make do with lambda expressions:
theorem exmpl (x : ℕ) : false :=
begin
let f : ℕ → ℕ := λ n, n + 1,
end
(Try changing that let to have to see how the context changes.)
Another way to do it is to use let expressions outside the tactic proof. These expressions do have syntax for arguments before the colon. For example,
theorem exmpl (x : ℕ) : false :=
let f (n : ℕ) : ℕ := n + x
in begin
end

Coq: Defining a function by pattern matching on the arity of its argument

I want to define a function, the behavior of which depends on whether it's argument is (at least) an n-place function. A rudimentary (failed) attempt is
Definition rT {y:Type}(x:y) := ltac: (match y with
| _ -> _ -> _ => exact True
| _ => exact False end).
Check prod: Type -> Type -> Type.
Compute rT prod. (*= False: Prop*)
Print rT. (*rT = fun (y : Type) (_ : y) => False: forall y : Type, y -> Prop*)
As you see, rT maps everything to False. Why? The result remains the same if I replace y in the match clause w/ type of x
The function you want cannot exist within Gallina at the type you expect.
Your function is accepted, but if you print it, you can see its body is:
rT = fun (y : Type) (_ : y) => False
Gallina has no way of match-ing on a Type. There are ways to deal with n-ary functions, in such a way that you can inspect their arity, but it involves dependent types to statically capture the arity. For instance, for uniform n-ary functions:
https://coq.inria.fr/library/Coq.Numbers.NaryFunctions.html

Order of Evaluation of Arguments in Ocaml

I would like to know why does ocaml evaluate the calls from right to left, is that a FP principle or it doesn't matter at all to a FP language ?
A quicksort example :
let rec qs = function
| [] -> []
| h::t -> let l, r = List.partition ((>) h) t in
List.iter (fun e -> print_int e; print_char ' ') l; Printf.printf " <<%d>> " h;
List.iter (fun e -> print_int e; print_char ' ') r; print_char '\n';
(qs l)#(h::qs r)
In my example the call to (qs r) is evaluated first and then (qs l) but I expected it to be otherwise.
# qs [5;43;1;10;2];;
1 2 <<5>> 43 10
10 <<43>>
<<10>>
<<1>> 2
<<2>>
- : int list = [1; 2; 5; 10; 43]
EDIT :
from https://caml.inria.fr/pub/docs/oreilly-book/html/book-ora029.html
In Objective CAML, the order of evaluation of arguments is not
specified. As it happens, today all implementations of Objective CAML
evaluate arguments from left to right. All the same, making use of
this implementation feature could turn out to be dangerous if future
versions of the language modify the implementation.
The order of evaluation of arguments to a function is not specified in OCaml.
This is documented in Section 6.7 of the manual.
In essence this gives the greatest possible freedom to the system (compiler or interpreter) to evaluate expressions in an order that is advantageous in some way. It means you (as an OCaml programmer) must write code that doesn't depend on the order of evaluation.
If your code is purely functional, its behavior can't depend on the order. So you need to be careful only when writing code with effects.
Update
If you care about order, use let:
let a = <expr1> in
let b = <expr2> in
f a b
Or, more generally:
let f = <expr0> in
let a = <expr1> in
let b = <expr2> in
f a b
Update 2
For what it's worth, the book you cite above was published in 2002. A lot has changed since then, including the name of the language. A more current resource is Real World OCaml.

Logic to test that 3 of 4 are True

I want to return True if and only if 3 out of 4 boolean values are true.
The closest I've gotten is (x ^ y) ^ (a ^ b):
What should I do?
I suggest writing the code in a manner that indicates what you mean. If you want 3 values to be true, it seems natural to me that the value 3 appears somewhere.
For instance, in C++:
if ((int)a + (int)b + (int)c + (int)d == 3)
...
This is well defined in C++: the standard (§4.7/4) indicates that converting bool to int gives the expected values 0 or 1.
In Java and C#, you can use the following construct:
if ((a?1:0) + (b?1:0) + (c?1:0) + (d?1:0) == 3)
...
#1: Using a branching ?: 3 or 4 operations
A ^ B ? C & D : ( C ^ D ) & A
#2 Non-Branching, 7 operations
(A ^ B ^ C ^ D) & ((A & B) | (C & D))
Back when I use to profile everything, I found non-branching solutions were quite a bit quicker operation-for-operation as the CPU could predict the code path better, and execute more operations in tandem. There is about 50% less work in the branching statement here though.
If this had been Python, I would have written
if [a, b, c, d].count(True) == 3:
Or
if [a, b, c, d].count(False) == 1:
Or
if [a, b, c, d].count(False) == True:
# In Python True == 1 and False == 0
Or
print [a, b, c, d].count(0) == 1
Or
print [a, b, c, d].count(1) == 3
Or
if a + b + c + d == 3:
Or
if sum([a, b, c, d]) == 3:
All these work, since Booleans are subclasses of integers in Python.
if len(filter(bool, [a, b, c, d])) == 3:
Or, inspired by this neat trick,
data = iter([a, b, c, d])
if not all(data) and all(data):
Long but very simple, (disjuntive) normal form:
(~a & b & c & d) | (a & ~b & c & d) | (a & b & ~c & d) | (a & b & c & ~d)
It may be simplified but that requires more thinking :P
Not sure it is simpler, but maybe.
((x xor y) and (a and b)) or ((x and y) and (a xor b))
If you want to use this logic in a programming language, my suggestion is
bool test(bool a, bool b, bool c, bool d){
int n1 = a ? 1 : 0;
int n2 = b ? 1 : 0;
int n3 = c ? 1 : 0;
int n4 = d ? 1 : 0;
return n1 + n2 + n3 + n4 == 3;
}
Or if you want, you can put all of these in a single line:
return (a ? 1 : 0) + (b ? 1 : 0) + (C ? 1 : 0) + (d ? 1 : 0) == 3;
Also you can generalize this problem to n of m :
bool test(bool *values, int n, int m){
int sum = 0;
for(int i = 0; i < m; i += 1){
sum += values[i] ? 1 : 0;
}
return sum == n;
}
This answer depends on the system of representation, but if 0 is the only value interpreted as false, and not(false) always returns the same numeric value, then not(a) + not(b) + not(c) + not(d) = not(0) should do the trick.
Keeping in mind that SO if for programming questions, rather than mere logical problems, the answer obviously depends on the choice of a programming language. Some languages support features that are uncommon to others.
For example, in C++ you could test your conditions with:
(a + b + c + d) == 3
This should be the fastest way to do the check in languages that support automatic (low-level) conversion from boolean to integer types. But again, there is no general answer for that problem.
The best I can do is ((x ^ y) ^ (a ^ b)) && ((a || x) && (b || y))
((a xor b) xor (c xor d)) and ((a or b) and (c or d))
The fist expression searchs for 1 or 3 true's out of 4. The second one eliminates 0 or 1 (and sometimes 2) true's out of 4.
Java 8, filter out the false values, and count the remaining true values:
public static long count(Boolean... values) {
return Arrays.stream(values).filter(t -> t).count();
}
Then you can use it as follows:
if (3 == count(a, b, c, d)) {
System.out.println("There... are... THREE... lights!");
}
Easily generalizes to checking for n of m items being true.
To check at least n out of all Boolean are true, ( n must be less than or equal to total number of Boolean :p)
if (((a ? 1:0) + (b ? 1:0 ) + (c ? 1:0) + (d ? 1:0 )) >= n) {
// do the rest
}
Edit : After #Cruncher's comment
To check 3 boolean out of 4
if (((a ? 1:0) + (b ? 1:0 ) + (c ? 1:0) + (d ? 1:0 )) == 3) {
// do the rest
}
Another one :
((c & d) & (a ^ b)) | ((a & b) & (c ^ d)) (Details)
Here's a way you could solve it in C# with LINQ:
bool threeTrue = new[] { a, b, x, y }.Count(x => x) == 3;
That is the symmetric Boolean function S₃(4). A symmetric Boolean function is a boolean function which only depends on the quantity of inputs set, but doesn't depend on which inputs they are. Knuth mentions functions of this type in section 7.1.2 in Volume 4 of The Art of Computer Programming.
S₃(4) can be computed with 7 operations as follows:
(x && y && (a || b)) ^ ((x || y) && a && b)
Knuth shows that this is optimal, meaning that you cannot do this in less than 7 operations using the normal operators: &&, || , ^, <, and >.
However if you want to use this in a language which uses 1 for true and 0 for false, you can also use addition easily:
x + y + a + b == 3
which makes your intention quite clear.
(a && b && (c xor d)) || (c && d && (a xor b))
From a pure logic point of view this is what I came up with.
By the pigeon hole principle, if exactly 3 are true, then either a and b is true, or c and d is true. Then its just a matter of anding each of those cases with exactly one of the other 2.
Wolfram truth table
If you use a logic visualization tool like Karnaugh Maps, you see that this is a problem where you can't avoid a full blown logic term if you want to write it in one if (...) line. Lopina showed it already, it's not possible to write it simpler. You can factor out a bit, but it will stay hard to read for you AND for the machine.
Counting solutions are not bad and they show what you are really after. How you do the counting efficiently depends on your programming language. The array solutions with Python oder LinQ are nice to look at, but beware, this is SLOW. Wolf's (a+b+x+y)==3 will work nicely and fast, but only if your language equates "true" with 1. If "true" is represented by -1, you will have to test for -3 :)
If your language uses true booleans, you could try to program it explicitly (I use != as XOR test):
if (a)
{
if (b)
return (x != y); // a,b=true, so either x or y must be true
else
return (x && y); // a=true, b=false, so x AND y must be true
}
else
{
if (b)
return (x && y); // a=false, b=true, so x and y must be true
else
return false; // a,b false, can't get 3 of 4
}
"x != y" works only if x,y are of a boolean type. If they are some other type where 0 is false and everything else is true, this can fail. Then use a boolean XOR, or ( (bool)x != (bool)y ), or write "if (x) return (y==false) else return (y==true);", which is a bit more work for the computer.
If your programming language provides the ternary ?: operator, you can shorten it to
if (a)
return b ? (x != y) : (x && y);
else
return b ? (x && y) : false;
which keeps a bit of readability, or cut it aggressively to
return a ? (b ? (x != y) : (x && y)) : (b ? (x && y) : false);
This code does exactly three logic tests (state of a, state of b, comparison of x and y) and should be faster than most of the other answers here. But you need to comment it, or you won't understand it after 3 months :)
There are a lot of good answers here; here is an alternate formulation which no one else has posted yet:
a ? (b ? (c ^ d) : (c && d)) : (b && c && d)
Similar to the first answer, but pure Java:
int t(boolean b) {
return (b) ? 1 : 0;
}
if (t(x) + t(y) + t(a) + t(b) == 3) return true;
return false;
I prefer counting them as integers because it makes for more readable code.
In Python, to see how many of an iterable of elements are True, use sum (it's quite straightforward):
Setup
import itertools
arrays = list(itertools.product(*[[True, False]]*4))
Actual Test
for array in arrays:
print(array, sum(array)==3)
Output
(True, True, True, True) False
(True, True, True, False) True
(True, True, False, True) True
(True, True, False, False) False
(True, False, True, True) True
(True, False, True, False) False
(True, False, False, True) False
(True, False, False, False) False
(False, True, True, True) True
(False, True, True, False) False
(False, True, False, True) False
(False, True, False, False) False
(False, False, True, True) False
(False, False, True, False) False
(False, False, False, True) False
(False, False, False, False) False
If you're after the on-the-paper (non-programming) solution, then K-maps and Quine-McCluskey algorithms are what you're after, they help you minify your boolean function.
In your case, the result is
y = (x̄3 ^ x2 ^ x1 ^ x0) ∨ (x3 ^ x̄2 ^ x1 ^ x0) ∨ (x3 ^ x2 ^ x̄1 ^ x0) ∨ (x3 ^ x2 ^ x1 ^ x̄0)
If you want to do this programmatically, non-fixed amount of variables and a custom "threshold", then simply iterating thru a list of boolean values and counting occurrences of "true" is pretty simple and straightforward.
I want to return true if and only if 3 out of 4 boolean values are true.
Given the 4 boolean values, a, b, x, y, this task translates into the following C statement:
return (a+b+x+y) == 3;
((a^b)^(x^y))&((a|b)&(x|y))
is what you want. Basically I took your code and added checking if actually 3 are true and not 3 are false.
A programming question without an answer involving recursion? Inconceivable!
There are enough "exactly 3 out of 4 trues" answers, but here's a generalised (Java) version for "exactly m out of n trues" (otherwise recursion isn't really worth it) just because you can:
public static boolean containsTrues(boolean[] someBooleans,
int anIndex, int truesExpected, int truesFoundSoFar) {
if (anIndex >= someBooleans.length) {
return truesExpected == truesFoundSoFar; // reached end
}
int falsesExpected = someBooleans.length - truesExpected;
boolean currentBoolean = someBooleans[anIndex];
int truesFound = truesFoundSoFar + (currentBoolean ? 1 : 0);
if (truesFound > truesExpected) {
return false;
}
if (anIndex - truesFound > falsesExpected) {
return false; // too many falses
}
return containsTrues(someBooleans, anIndex + 1, truesExpected,
truesFound);
}
This could be called with something like:
boolean[] booleans = { true, false, true, true, false, true, true, false };
containsTrues(booleans, 0, 5, 0);
which should return true (because 5 of 8 values were true, as expected). Not quite happy with the words "trues" and "falses", but can't think of a better name right now.... Note that the recursion stops when too many true or too many false values have been found.
Since readability is a big concern, you could use a descriptive function call (wrapping any of the suggested implementations). If this calculation needs to be done in multiple places, a function call is the best way to achieve reuse, and makes it clear exactly what you are doing.
bool exactly_three_true_from(bool cond1, bool cond2, bool cond3, bool cond4)
{
//...
}
In PHP, making it more dynamic (just in case you change number of conditions, etc.):
$min = 6;
$total = 10;
// create our boolean array values
$arr = array_map(function($a){return mt_rand(0,1)>0;},range(1,$total));
// the 'check'
$arrbools = array_map(function($a){return (int)$a;},$arr);
$conditionMet = array_sum($arrbools)>=$min;
echo $conditionMet ? "Passed" : "Failed";
(((a AND b) OR (x AND y)) AND ((a XOR b) OR (x XOR y)))
While I could show that this is a good solution, Sam Hocevar's answer is easy both to write and understand later. In my book that makes it better.
Here is some c# code I just wrote because you have inspired me:
It takes any amount of arguments and will tell you if n of them are true.
static bool boolTester(int n, params bool[] values)
{
int sum = 0;
for (int i = 0; i < values.Length; i++)
{
if (values[i] == true)
{
sum += 1;
}
}
if( sum == n)
{
return true;
}
return false;
}
and you call it like so:
bool a = true;
bool b = true;
bool c = true;
bool d = false;
bool test = false;
test = boolTester(3, a, b, c, d);
So you can now test 7/9 or 15/100 as you will.

check if a tree is complete standard ml

I want to make a function in standard ml that checks if a tree is complete or not, the function somehow works, but its giving me the wrong type and a warning of non-exhaustive cases
The tree code:
datatype 'data tree =
EMPTY
| NODE of 'data tree * 'data * 'data tree;
fun isComplete EMPTY = true
| isComplete (NODE(x, y, z)) = if (x = EMPTY andalso z <> EMPTY) orelse (x <> EMPTY andalso z = EMPTY) then false else true;
Now the above function's type is: ''a tree -> bool but the required type is 'a tree -> bool
The warning I'm having is:
stdIn:169.8 Warning: calling polyEqual
stdIn:169.26 Warning: calling polyEqual
stdIn:169.45-169.47 Warning: calling polyEqual
stdIn:169.64-169.66 Warning: calling polyEqual
stdIn:124.1-169.94 Warning: match nonexhaustive
NODE (x,y,z) => ...
What is the problem I'm having?
EDIT:
Thanks to Michael, I fixed the code and now it works:
- fun isComplete EMPTY = true
| isComplete (NODE(EMPTY, _, EMPTY)) = true
| isComplete (NODE(NODE(x, y, z), _, NODE(a, b, c))) = true
| isComplete (EMPTY, _, NODE(x, y, z)) = false
| isComplete (NODE(x, y, z), _, EMPTY) = false;
The ''a tree -> bool type indicates that a is an equality type: it must be a type that supports testing with equals. Since you are using = and <> to test x and z, the tree data must support equality (even though you're not doing anything interesting with the values). This is the root of the polyEqual warning.
The nonexhaustive match warning is more puzzling. When I paste your datatype and function definitions into Moscow ML, I do not get a warning. I don't think I'd worry about it too much, as I'd expect fixing the type to also take care of the warning.
To get the desired type 'a tree -> bool, I'd suggest getting rid of the if in favor of pattern matching. E.g.:
fun isComplete EMPTY = true
| isComplete (NODE(EMPTY, _, EMPTY)) = true
| isComplete (NODE(EMPTY, _, NODE(x,y,z))) = false
| ... (* fill out the rest of the cases *)
I'll leave it to you to figure out the full set of cases, as this looks like homework.
Incidentally, I don't think your test for completeness is correct. Consider what happens when neither subtree is EMPTY: you call the tree complete without considering the contents. This doesn't have anything to do with the warnings you're seeing, though.
Concerning the polyEqual warning: in SML/NJ this warning is printed everytime you use this operator, but that doesn't mean your code is faulty. Here's a blog post about it, and in the comments someone explains why the warning is given: http://abstractfactory.blogspot.fr/2006/05/sml-hacking-tip-turn-off-polyequal.html