Filter function in nonogram solver - function

I have to understand the Deductive solver By Ted Yin from https://wiki.haskell.org/Nonogram
i don't know how
elim b w ps = filter (\p -> all (\x -> x `elem` p) b &&
all (\x -> x `notElem` p) w) ps
works. I only know that
all (\x -> x `notElem` [1]) [1,2,3,4]
gives False, and
all (\x -> x `elem` [1]) [1,1,1,1]
gives True.
but i don't know hot to run all elim function and how it works

First, help yourself to a little whitespace to aid understanding, and name your subexpressions:
elim b w ps = filter (\p -> all (\x -> x `elem` p) b &&
all (\x -> x `notElem` p) w
) ps
= filter foo ps
where
foo p = all (\x -> x `elem` p) b &&
all (\x -> x `notElem` p) w
= filter foo ps
where
foo p = all tst1 b && all tst2 w
where
tst1 = (\x -> x `elem` p)
tst2 = (\x -> x `notElem` p)
= filter foo ps
where
foo p = (&&) (all tst1 b) (all tst2 w)
where
tst1 x = elem x p
tst2 y = notElem y p
Now what does that do? Or better yet, what is it? Let's go by some types to build up our insight here:
filter :: (a -> Bool) -> [a] -> [a]
foo :: a -> Bool
ps :: [a]
filter foo ps :: [a]
p :: a
foo p :: Bool
(&&) :: Bool -> Bool -> Bool
all tst1 b :: Bool
all tst2 w :: Bool
---------------------------
all :: (t -> Bool) -> [t] -> Bool
tst1 :: t -> Bool
tst2 :: t -> Bool
b :: [t]
w :: [t]
---------------------------
......
---------------------------
elim b w ps :: [a]
elim :: [t] -> [t] -> [a] -> [a]
Complete the picture by working through the types of tst1 and tst2 to find out the relationship between the t and a types.
tst1 :: t -> Bool -- tst1 x = elem x p
tst2 :: t -> Bool -- tst2 y = notElem y p
x :: t
y :: t
elem :: Eq t => t -> [t] -> Bool
notElem :: Eq t => t -> [t] -> Bool
p :: [t] -- it was : a !
Thus a ~ [t] and [a] ~ [[t]] and finally,
elim b w ps :: [[t]]
elim :: Eq t => [t] -> [t] -> [[t]] -> [[t]]
So then filter foo leaves only those ps in ps for which foo p == True.
And that means all tst1 b == True and all tst2 w == True.
And that means, every x in b is an element of p, and every y in w is not an element in p. Or in other words only such ps in ps are left alone in the resulting list for which
foo p = (b \\ p) == [] && (p \\ w) == p
holds:
import Data.List (\\)
elim b w ps = [ p | p <- ps, (b \\ p) == [], (p \\ w) == p ]

Related

How to write my own Haskell sortOn function

I was wondering how to write my own sortOn function.
I made a sortBy function and an on function as shown bellow but can't figure out how to combine them and what additional code to add. sortOn is like sortBy but the given function (in here named comp) is applied only once for every element of the list
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
sortBy comp [] = []
sortBy comp [x] = [x]
sortBy comp (x:xs) = insert x (sortBy comp xs)
where
insert x [] = [x]
insert x (y:ys)
| (comp x y == LT) || (comp x y == EQ) = x:y:ys
| otherwise = y:(insert x ys)
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
on b f x y = b (f x) (f y)
Here's a hint.
If you have a list [a] and you just sort it, the sort function will implicitly make use of the Ord instance for a and specifically the function:
compare :: a -> a -> Ordering
to figure out the relative ordering of pairs of a elements.
Now, if you have a list [a] and a transformation function b, and you want to use sortOn to sort the list of the transformed values, you'll need to figure out the relative ordering of pairs of b elements. How will you do this? Well, you'll implicitly use the Ord instance for b and specifically the function:
compare :: b -> b -> Ordering
In other words, when you try to define:
sortOn :: (Ord b) => (a -> b) -> [a] -> [a]
sortOn f lst = ...
you'll have arguments of type:
f :: a -> b
lst :: [a]
and additional objects of type:
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
compare :: b -> b -> Ordering
Now, can you see how to put them together to define sortOn?
SPOILERS
Further hint: What's the type of compare `on` f?
Further further hint: It's a -> a -> Ordering.

How can I have Idris automatically prove that two values are not equal?

How can I have Idris automatically prove that two values are not equal?
p : Not (Int = String)
p = \Refl impossible
How can I have Idris automatically generate this proof? auto does not appear to be capable of proving statements involving Not. My end goal is to have Idris automatically prove that all elements in a vector are unique and that two vectors are disjoint.
namespace IsSet
data IsSet : List t -> Type where
Nil : IsSet []
(::) : All (\a => Not (a = x)) xs -> IsSet xs -> IsSet (x :: xs)
namespace Disjoint
data Disjoint : List t -> List t -> Type where
Nil : Disjoint [] ys
(::) : All (\a => Not (a = x)) ys -> Disjoint xs ys -> Disjoint (x :: xs) ys
f : (xs : List Type) -> (ys: List Type) -> {p1 : IsSet xs} -> {p2 : IsSet ys} -> {p3 : Disjoint xs ys} -> ()
f _ _ = ()
q : ()
q = f ['f1, 'f2] ['f3, 'f4]
Using %hint I got Idris to auto prove any NotEq it encountered. Since Not (a = b) is a function (since Not a is a -> Void), I needed to make NotEq (since auto cannot prove functions).
module Main
import Data.Vect
import Data.Vect.Quantifiers
%default total
fromFalse : (d : Dec p) -> {auto isFalse : decAsBool d = False} -> Not p
fromFalse (Yes _) {isFalse = Refl} impossible
fromFalse (No contra) = contra
data NotEq : a -> a -> Type where
MkNotEq : {a : t} -> {b : t} -> Not (a = b) -> NotEq a b
%hint
notEq : DecEq t => {a : t} -> {b : t} -> {auto isFalse : decAsBool (decEq a b) = False} -> NotEq a b
notEq = MkNotEq (fromFalse (decEq _ _))
NotElem : k -> Vect n k -> Type
NotElem a xs = All (\x => NotEq a x) xs
q : (a : lbl) -> (b : Vect n lbl) -> {auto p : NotElem a b} -> ()
q _ _ = ()
w : ()
w = q "a" ["b","c"]

Why can foldr take a function with three arguments?

I was having a look at some list operations and came across !!:
(!!) :: [a] -> Int -> a
xs !! n
| n < 0 = negIndex
| otherwise = foldr (\x r k -> case k of
0 -> x
_ -> r (k-1)) tooLarge xs n
The function (\x r k -> ...) has type a -> (Int -> a) -> Int -> a, but foldr takes a function that should only accept two arguments:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys
Can someone explain to me why foldr accepts a function that takes 3 arguments with the following type a -> (Int -> a) -> Int -> a? Especially since the result should have the same type as the second argument?
-> is right-associative. So a -> b -> c is a -> (b -> c). Therefore, your type
a -> (Int -> a) -> Int -> a
is the same as
a -> (Int -> a) -> (Int -> a)
and we can see that it fits foldr's type quite well.
(more explanation for others ;)
(!!) :: [a] -> Int -> a
xs !! n
| n < 0 = negIndex
| otherwise = foldr (\x r k -> case k of
0 -> x
_ -> r (k-1)) tooLarge xs n
foldr :: (a -> b -> b) -> b -> [a] -> b
-- ^1 ^2
foldr commonly makes an accumulated(?) value. In this case, foldr makes an
accumulated function (b) of the type (Int -> a)! foldr ... tooLarge xs is evaluated to an
accumulated function, and this accumulated function (^2) takes an argument n. ^1 is a tooLarge function. Interestingly, the buildup of this
accumulated function depends on the value of a free variable n (i.e., k).
For example, ['a', 'b', 'c'] !! 2 is evaluated like below:
\x r k = \'a' r 2 -> r (2-1) (r is not known yet, and drives further evaluations.)
\x r k = \'b' r 1 -> r (1-1)
\x r k = \'c' r 0 -> 'c'
['a', 'b', 'c'] !! 3 goes like this:
\x r k = \'a' r 3 -> r (3-1)
\x r k = \'b' r 2 -> r (2-1)
\x r k = \'c' r 1 -> r (1-1) (r turns out to be tooLarge.) = tooLarge (1-1) (ERROR!)
You can check debug traces:
module Main where
import Debug.Trace
tooLarge _ = errorWithoutStackTrace "!!!: index too large"
negIndex = errorWithoutStackTrace "!!!: negative index"
(!!!) :: Show a => [a] -> Int -> a
xs !!! n
| n < 0 = negIndex
| otherwise = foldr (\x r k -> trace ("x: " ++ show x ++ ", k: " ++ show k) $
case k of
0 -> x
_ -> r (k-1)) tooLarge xs n
main = do
print $ ['a', 'b', 'c'] !!! 2
print $ ['a', 'b', 'c'] !!! 3
-- x: 'a', k: 2
-- x: 'b', k: 1
-- x: 'c', k: 0
-- 'c'
-- x: 'a', k: 3
-- x: 'b', k: 2
-- x: 'c', k: 1
-- sample: !!!: index too large
This (!!) implementation is a report version. The report version of the prelude is more efficient than a familiar naive recursive implementation,
due to optimizations of foldr.

Can this function be implemented?

Is there any implementation for this function?
foo :: (Monad m, Monad n) => m a -> n a -> (a -> a -> a) -> m (n a)
foo x y f = ...
Yes, and it can be given a more general type.
foo :: (Functor f, Functor g) => (a -> b -> c) -> f a -> g b -> f (g c)
foo f fx gy = fmap (\x -> fmap (f x) gy) fx

Idris proof by definition

I can write the function
powApply : Nat -> (a -> a) -> a -> a
powApply Z f = id
powApply (S k) f = f . powApply k f
and prove trivially:
powApplyZero : (f : _) -> (x : _) -> powApp Z f x = x
powApplyZero f x = Refl
So far, so good. Now, I try to generalize this function to work with negative exponents. Of course, an inverse must be provided:
import Data.ZZ
-- Two functions, f and g, with a proof that g is an inverse of f
data Invertible : Type -> Type -> Type where
MkInvertible : (f : a -> b) -> (g : b -> a) ->
((x : _) -> g (f x) = x) -> Invertible a b
powApplyI : ZZ -> Invertible a a -> a -> a
powApplyI (Pos Z) (MkInvertible f g x) = id
powApplyI (Pos (S k)) (MkInvertible f g x) =
f . powApplyI (Pos k) (MkInvertible f g x)
powApplyI (NegS Z) (MkInvertible f g x) = g
powApplyI (NegS (S k)) (MkInvertible f g x) =
g . powApplyI (NegS k) (MkInvertible f g x)
I then try to prove a similar statement:
powApplyIZero : (i : _) -> (x : _) -> powApplyI (Pos Z) i x = x
powApplyIZero i x = ?powApplyIZero_rhs
However, Idris refuses to evaluate the application of powApplyI, leaving the type of ?powApplyIZero_rhs as powApplyI (Pos 0) i x = x (yes, Z is changed to 0). I've tried writing powApplyI in a non-pointsfree style, and defining my own ZZ with the %elim modifier (which I don't understand), but neither of these worked. Why isn't the proof handled by inspecting the first case of powApplyI?
Idris version: 0.9.15.1
Here are some things:
powApplyNI : Nat -> Invertible a a -> a -> a
powApplyNI Z (MkInvertible f g x) = id
powApplyNI (S k) (MkInvertible f g x) = f . powApplyNI k (MkInvertible f g x)
powApplyNIZero : (i : _) -> (x : _) -> powApplyNI 0 i x = x
powApplyNIZero (MkInvertible f g y) x = Refl
powApplyZF : ZZ -> (a -> a) -> a -> a
powApplyZF (Pos Z) f = id
powApplyZF (Pos (S k)) f = f . powApplyZF (Pos k) f
powApplyZF (NegS Z) f = f
powApplyZF (NegS (S k)) f = f . powApplyZF (NegS k) f
powApplyZFZero : (f : _) -> (x : _) -> powApplyZF 0 f x = x
powApplyZFZero f x = ?powApplyZFZero_rhs
The first proof went fine, but ?powApplyZFZero_rhs stubbornly keeps the type powApplyZF (Pos 0) f x = x. Clearly, there's some problem with ZZ (or my use of it).
The problem: powApplyI was not provably total, according to Idris. Idris' totality checker relies on being able to reduce parameters to structurally smaller forms, and with raw ZZs, this doesn't work.
The answer is to delegate the recursion to plain old powApply (which is proven total):
total
powApplyI : ZZ -> a <~ a -> a -> a
powApplyI (Pos k) (MkInvertible f g x) = powApply k f
powApplyI (NegS k) (MkInvertible f g x) = powApply (S k) g
Then, with a case split on i, powApplyIZero is proven trivially.
Thanks to Melvar from the #idris IRC channel.
powApplyI (Pos Z) i x doesn't reduce further because i is not in weak head normal form.
I don't have an Idris compiler, so I rewrote your code in Agda. It's pretty similar:
open import Function
open import Relation.Binary.PropositionalEquality
open import Data.Nat
open import Data.Integer
data Invertible : Set -> Set -> Set where
MkInvertible : {a b : Set} (f : a -> b) -> (g : b -> a) ->
(∀ x -> g (f x) ≡ x) -> Invertible a b
powApplyI : {a : Set} -> ℤ -> Invertible a a -> a -> a
powApplyI ( + 0 ) (MkInvertible f g x) = id
powApplyI ( + suc k ) (MkInvertible f g x) = f ∘ powApplyI ( + k ) (MkInvertible f g x)
powApplyI -[1+ 0 ] (MkInvertible f g x) = g
powApplyI -[1+ suc k ] (MkInvertible f g x) = g ∘ powApplyI -[1+ k ] (MkInvertible f g x)
Now you can define your powApplyIZero as
powApplyIZero : {a : Set} (i : Invertible a a) -> ∀ x -> powApplyI (+ 0) i x ≡ x
powApplyIZero (MkInvertible _ _ _) _ = refl
Pattern-matching on i induces unification and powApplyI (+ 0) i x becomes replaced with powApplyI (+ 0) i (MkInvertible _ _ _), so powApplyI can proceed further.
Or you could write this explicitly:
powApplyIZero : {a : Set} (f : a -> a) (g : a -> a) (p : ∀ x -> g (f x) ≡ x)
-> ∀ x -> powApplyI (+ 0) (MkInvertible f g p) x ≡ x
powApplyIZero _ _ _ _ = refl