Proof a Natural (n) is Zero - proof

I am trying to learn the idris paradigm and still struggling. Here i have a function isZero that takes some natural Nat and returns True or False.
My issue is with the non-relexive case.
namespace Numbers
data Nat : Type where
Zero : Numbers.Nat
Successor : Numbers.Nat -> Numbers.Nat
isZero: Numbers.Nat -> Prelude.Bool.Bool
isZero Zero = True
isZero _ = False
isNotZero: Numbers.Nat -> Prelude.Bool.Bool
isNotZero Zero = False
isNotZero _ = True
proofNIsZero : (n : Numbers.Nat) -> isZero n = Bool.True
proofNIsZero Zero = Refl
proofNIsZero (Successor _) = ?rhs
It seems obvious to reason that some Successor to any Nat cannot be Zero. But my struggle is in the proof. The Type of the ?rhs hole is
--------------------------------------
rhs : False = True
Trying to navigate what I think should be (and will one day be) simple has led to uninhabited, Void, absurd and impossible. None of which I can disambiguate.
Perhaps those are the keys - but I cannot decipher!

I am answering as I think I relaized that perphaps the proof above wasn't stated correctly. I added the statement that asserted n = Zero, which allow for the isZero n = Bool.True to have meaning. the n = Zero carries forward as prf and allows me to declare absurd prf as isZero n = Bool.True cannot hold true if n is Successor to some Nat.
Uninhabited (Successor _ = Zero) where
uninhabited Refl impossible
proofNIsZero : (n : Numbers.Nat) -> n = Zero -> isZero n = Bool.True
proofNIsZero Zero prf = Refl
proofNIsZero (Successor _) prf = absurd prf
Is there another approach or way to think of defining these as to not get caught in a pitfall?

Related

Idris proof with simplification causing "type mismatch" error

I am learning Idris by following along with this book: https://idris-hackers.github.io/software-foundations/pdf/sf-idris-2018.pdf
I kind of hit a snag when getting to the section on proof with simplification (yes it is right at the start). The small bit of code I am working on is:
namespace Numbers
data Nat : Type where
Zero : Numbers.Nat
Successor : Numbers.Nat -> Numbers.Nat
plus : Numbers.Nat -> Numbers.Nat -> Numbers.Nat
plus Zero b = b
plus (Successor a) b = Successor(plus a b)
These simpler proofs work okay:
One : Numbers.Nat
One = Successor Zero
Two : Numbers.Nat
Two = Successor One
Three : Numbers.Nat
Three = Successor Two
proofOnePlusZero : plus One Zero = One
proofOnePlusZero = Refl
proofOnePlusZero' : plus Zero One = One
proofOnePlusZero' = Refl
however as I tried to copy in the more complicated proof I get an error
-- works
plus_Z_n : (n : Numbers.Nat) -> plus Zero n = n
plus_Z_n n = Refl
-- breaks / errors
plus_Z_n' : (n : Numbers.Nat) -> plus n Zero = n
plus_Z_n' n = Refl
This is the error
When checking right hand side of plus_Z_n' with expected type
plus n One = Successor n
Type mismatch between
Successor n = Successor n (Type of Refl)
and
plus n (Successor Zero) = Successor n (Expected type)
Specifically:
Type mismatch between
Successor n
and
plus n (Successor Zero)
this is the expected behavior - however the recommendation is that one is able to understand why. I am at a loss and looking for hints or how to conisder this.
Here Idris just follows the definition (“proof of simplification”). So take plus Zero n = n. To simplify this type, the definition of plus helps: one branch defines plus Zero b = b. So we can replace plus Zero n with n to get to n = n, voilà. On the other hand, if trying to simplify plus n Zero = n, none of the branches in the definition of plus matches plus n Zero. So no replacement can be done and Idris is stuck with plus n Zero = n, until you help f.e. by case-splitting on n.
More precisely, if Idris tries to replace plus x Zero, it goes through all of the branches one by one and tries to match them, just as it would evaluate it. If it could be matched, it will stop. But only if the branch is equal to plus x Zero, it will be replaced. So given:
plus : Numbers.Nat -> Numbers.Nat -> Numbers.Nat
plus Zero b = b
plus a Zero = a
plus (Successor a) b = Successor(plus a b)
plus1 : plus n Zero = n
plus1 = Refl
This won't compile, because plus n Zero could be handled by plus Zero b = b, depending on what n is. But because n is not known, Idris already stops here, but does not replace it. So the second branch is not reached.

Appending nil to a dependently typed length indexed vector in Lean

Assume the following definition:
def app {α : Type} : Π{m n : ℕ}, vector α m → vector α n → vector α (n + m)
| 0 _ [] v := by simp [add_zero]; assumption
| (nat.succ _) _ (h :: t) v' := begin apply vector.cons,
exact h,
apply app t v'
end
Do note that (n + m) are flipped in the definition, so as to avoid plugging add_symm into the definition. Also, remember that add / + is defined on rhs in Lean. vector is a hand rolled nil / cons defined length indexed list.
So anyway, first we have a lemma that follows from definition:
theorem nil_app_v {α : Type} : ∀{n : ℕ} (v : vector α n),
v = [] ++ v := assume n v, rfl
Now we have a lemma that doesn't follow from definition, as such I use eq.rec to formulate it.
theorem app_nil_v {α : Type} : ∀{n : ℕ} (v : vector α n),
v = eq.rec (v ++ []) (zero_add n)
Note that eq.rec is just C y → Π {a : X}, y = a → C a.
The idea of a proof is trivial by induction on v. The base case follows immediately from definition, the recursive case should follow immediately from the inductive hypothesis and definition, but I can't convince Lean of this.
begin
intros n v,
induction v,
-- base case
refl,
-- inductive case
end
The inductive hypothesis I get from Lean is a_1 = eq.rec (a_1 ++ vector.nil) (zero_add n_1).
How do I use it with conclusion a :: a_1 = eq.rec (a :: a_1 ++ vector.nil) (zero_add (nat.succ n_1))? I can unfold app to reduce the term a :: a_1 ++ vector.nil to a :: (a_1 ++ vector.nil), and now I am stuck.

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

Creating higher order functions using Haskell

I have recently been teaching myself Haskell, and one of my exercises was to implement a function that takes two arguments: a list and a single value. The function would check if the value is in the list twice or more. I cannot use the function element or member.
I tried removing the values that are not equal to the value. Then checking for the size of the new list if its more than 1 then it outputs True if not it outputs False. I having problem trying to use a function inside a function.
remove2 val [] = []
remove2 val (x:xs) = if ( not (x == val))
then remove2 val xs
else x:remove2 val xs
isMemberTwice :: (Eq val) => val -> [val] -> Bool
isMemberTwice val [] = False
isMemberTwice val (x:xs)
| ( >= (length (remove2 val [val])) 2) = True
| otherwise = a `isMemberTwice’` xs
A higher order function is a function that takes another function as argument or returns another function.
Your problem at hand is easily solvable using a short recursive function:
memtwice :: (Eq a) => a -> [a] -> Bool
memtwice value list = scan value list False
where scan _ [] _ = False
scan v (x:xs) True =
if v == x then True
else scan v xs True
scan v (x:xs) False =
scan v xs (v == x)
The scan is a function that carries state information (whether there has already been found one instance) as additional parameter.
One could rewrite this using higher order functions such as fold though I'm not sure how one could implement the short circuit behaviour (stopping as soon as two instances have been found) then.
Every function on a list can be written in this form:
f [] = ... -- also called the "base case"
f (a:as) = ... -- also called the recursive case
Let's apply this idea to writing a function which determine the number 3 appears in a list at least once:
hasA3 :: [Int] -> Bool
hasA3 [] = ...
hasA3 (a:as) = ...
Clearly hasA3 [] = False. I'll leave you to figure out how to write the recursive case. Hint: the function might have to check if a == 3.
Now let's write a function which determines if a list contains two or more threes. Again we start with the two cases:
hasTwo3s :: [Int] -> Bool
hasTwo3s [] = ...
hasTwo3s (a:as) = ...
Again, the base case is easy. Hints for the recursive case: you might have to check if a == 3 and then you might want to use the hasA3 function.
I will add to Daniel Jour's answer starting from its final note:
One could rewrite this using higher order functions such as fold
though I'm not sure how one could implement the short circuit
behaviour (stopping as soon as two instances have been found) then.
Let's transform the original code:
memtwice value list = scan value list False
where scan _ [] _ = False
scan v (x:xs) True =
if v == x then True
else scan v xs True
scan v (x:xs) False =
scan v xs (v == x)
Moving to boolean operators we get:
memtwice value list = scan value list False
where scan _ [] _ = False
scan v (x:xs) True = v == x || scan v xs True
scan v (x:xs) False = scan v xs (v == x)
Now, the parameter v is always value, so let's remove the parameter.
memtwice value list = scan list False
where scan [] _ = False
scan (x:xs) True = value == x || scan xs True
scan (x:xs) False = scan xs (value == x)
Introducing an explicit lambda for the last argument (not really needed, but helps readability):
memtwice value list = scan list False
where scan [] = (\_ -> False)
scan (x:xs) = \found -> if found
then value == x || scan xs True
else scan xs (value == x)
We now see that the last recursion pattern is a foldr: indeed we have a base-case definition for scan [], and the recursive case scan (x:xs) is defined only in terms of scan xs.
memtwice value list = foldr go (\_ -> False) list False
where go x next = \found -> if found
then value == x || next True
else next (value == x)
Note that foldr seems to be called with four parameters. This is because go x next produces a function, hence foldr go (\_ -> False) list does as well. We can now revert the explicit lambda.
memtwice value list = foldr go (\_ -> False) list False
where go x next True = value == x || next True
go x next False = next (value == x)
Finally, note that since || has short-circuiting behaviour, we did achieve an equivalent foldr to the original code.
There's an easier way really:
isMemberTwice needle haystack = n >= 2
where n = length $ filter (== needle) haystack
However, the downside with this approach is that, if you pass it a really long list, it'll evaluate the entire list, which is unnecessary: you only need to see if there are at least 2 occurrences of needle.
So a better solution is to avoid using length on the filtered list and instead just use pattern match: if it matches (_:_:_), there must be at least 2 occurrences:
isMemberTwice needle haystack = case occurrences of (_:_:_) -> True
_ -> False
where occurrences = filter (== needle) haystack

returning two different types from one function

How can I return values of multiple types from a single function?
I want to do something like:
take x y | x == [] = "error : empty list"
| x == y = True
| otherwise = False
I have a background in imperative languages.
There is a type constructor called Either that lets you create a type that could be one of two types. It is often used for handling errors, just like in your example. You would use it like this:
take x y | x == [] = Left "error : empty list"
| x == y = Right True
| otherwise = Right False
The type of take would then be something like Eq a => [a] -> [a] -> Either String Bool. The convention with Either for error handling is that Left represents the error and Right represents the normal return type.
When you have an Either type, you can pattern match against it to see which value it contains:
case take x y of
Left errorMessage -> ... -- handle error here
Right result -> ... -- do what you normally would
There is several solutions to your problem, depending on your intention : do you want to make manifest in your type that your function can fail (and in this case do you want to return the cause of the failure, which may be unnecessary if there is only one mode of failure like here) or do you estimate that getting an empty list in this function shouldn't happen at all, and so want to fail immediately and by throwing an exception ?
So if you want to make explicit the possibility of failure in your type, you can use Maybe, to just indicate failure without explanation (eventually in your documentation) :
take :: (Eq a) => [a] -> [a] -> Maybe Bool
take [] _ = Nothing
take x y = x == y
Or Either to register the reason of the failure (note that Either would be the answer to "returning two types from one function" in general, though your code is more specific) :
take :: (Eq a) => [a] -> [a] -> Either String Bool
take [] _ = Left "Empty list"
take x y = Right $ x == y
Finally you can signal that this failure is completely abnormal and can't be handled locally :
take :: (Eq a) => [a] -> [a] -> Bool
take [] _ = error "Empty list"
take x y = x == y
Note that with this last way, the call site don't have to immediately handle the failure, in fact it can't, since exceptions can only be caught in the IO monad. With the first two ways, the call site have to be modified to handle the case of failure (and can), if only to itself call "error".
There is one final solution that allows the calling code to choose which mode of failure you want (using the failure package http://hackage.haskell.org/package/failure ) :
take :: (Failure String m, Eq a) => [a] -> [a] -> m Bool
take [] _ = failure "Empty list"
take x y = return $ x == y
This can mimics the Maybe and the Either solution, or you can use take as an IO Bool which will throw an exception if it fails. It can even works in a [Bool] context (returns an empty list in case of failure, which is sometimes useful).
You can use the error functions for exceptions:
take :: Eq a => [a] -> [a] -> Bool
take [] _ = error "empty list"
take x y = x == y
The three answers you've gotten so far (from Tikhon Jelvis, Jedai and Philipp) cover the three conventional ways of handling this sort of situation:
Use the error function signal an error. This is often frowned upon, however, because it makes it hard for programs that use your function to recover from the error.
Use Maybe to indicate the case where no Boolean answer can be produced.
Use Either, which is often used to do the same thing as Maybe, but can additionally include more information about the failure (Left "error : empty list").
I'd second the Maybe and Either approach, and add one tidbit (which is slightly more advanced, but you might want to get to eventually): both Maybe and Either a can be made into monads, and this can be used to write code that is neutral between the choice between those two. This blog post discusses eight different ways to tackle your problem, which includes the three mentioned above, a fourth one that uses the Monad type class to abstract the difference between Maybe and Either, and yet four others.
The blog entry is from 2007 so it looks a bit dated, but I managed to get #4 working this way:
{-# LANGUAGE FlexibleInstances #-}
take :: (Monad m, Eq a) => [a] -> [a] -> m Bool
take x y | x == [] = fail "error : empty list"
| x == y = return True
| otherwise = return False
instance Monad (Either String) where
return = Right
(Left err) >>= _ = Left err
(Right x) >>= f = f x
fail err = Left err
Now this take function works with both cases:
*Main> Main.take [1..3] [1..3] :: Maybe Bool
Just True
*Main> Main.take [1] [1..3] :: Maybe Bool
Just False
*Main> Main.take [] [1..3] :: Maybe Bool
Nothing
*Main> Main.take [1..3] [1..3] :: Either String Bool
Right True
*Main> Main.take [1] [1..3] :: Either String Bool
Right False
*Main> Main.take [] [1..3] :: Either String Bool
Left "error : empty list"
Though it's important to note that fail is controversial, so I anticipate reasonable objections to this approach. The use of fail here is not essential, though—it could be replaced with any function f :: (Monad m, ErrorClass m) => String -> m a such that f err is Nothing in Maybe and Left err in Either.