Divide the vector in Idris: why can't combine 0 and m + n?

I would like to split the vector into two new vectors.

We cannot know how long individual vectors are, but the sum of the resulting vectors must be equal to the argument. I tried to capture this property as follows:

partition : (a -> Bool) -> Vect (m+n) a -> (Vect m a, Vect n a)
partition p [] = ([], [])
partition p (x::xs)
  = let (ys,zs) = partition p xs
  in case p xs of
    True  => (x::ys, zs)
    False => (ys, zs)

But Idris reports (pointing to section p [] "), which when developing the left side of Main.partition:

Can't unify
        Vect 0 a
with
        Vect (m + n) a

Specifically:
        Can't unify
                0
        with
                plus m n

Why is this so?

It seems quite obvious to me that if "0 = m + n" than m = n = 0. How can I convince Idris of this?

+4
source share
1 answer

, unification , , Idris, . , !

Idris , , , n + m = 0, m = 0 n = 0:

sumZero : (n, m : Nat) -> plus n m = Z -> (n=Z, m=Z)
sumZero Z m prf = (refl, prf)
sumZero (S k) m refl impossible

, .

: , " m n p a, plus m n, , m n". , , , , m n !

, partition, , n, , n. , . " , n", " m m' , m m' n".

:

partition : (a -> Bool) -> Vect n a -> (m ** (m' ** (Vect m a, Vect m' a, m+m'=n)))

:

partition : (a -> Bool) -> Vect n a -> (m ** (m' ** (Vect m a, Vect m' a, m+m'=n)))
partition p [] = (Z ** (Z ** ([], [], refl)))
partition p (x :: xs) with (p x, partition p xs)
  | (True, (m ** (m' ** (ys, ns, refl)))) = (S m ** (m' ** (x::ys, ns, refl)))
  | (False, (m ** (m' ** (ys, ns, refl)))) =
      (m ** (S m' ** (ys, x::ns, sym (plusSuccRightSucc m m'))))

, . Vect:

partition p [] = (Z ** (Z ** ([], [], refl)))

, , , refl. , n Z - n Nil of Vect.

. with, , if , p x .

partition p (x :: xs) with (p x, partition p xs)

True . plus , , refl, :

  | (True, (m ** (m' ** (ys, ns, refl)))) = (S m ** (m' ** (x::ys, ns, refl)))

False , plus m (S m') S (plus m m'). , , , ? plusSuccRightSucc , :

  | (False, (m ** (m' ** (ys, ns, refl)))) =
      (m ** (S m' ** (ys, x::ns, sym (plusSuccRightSucc m m'))))

, plusSuccRightSucc:

plusSuccRightSucc : (left : Nat) ->
                    (right : Nat) ->
                    S (plus left right) = plus left (S right)

sym:

sym : (l = r) -> r = l

, , , Vect. , , p, not p:

partition' : (p : a -> Bool) ->
             (xs : Vect n a) ->
             (m ** (m' ** (Vect m (y : a ** so (p y)),
                           Vect m' (y : a ** so (not (p y))),
                           m+m'=n)))
partition' p [] = (0 ** (0 ** ([], [], refl)))
partition' p (x :: xs) with (choose (p x), partition' p xs)
  partition' p (x :: xs) | (Left oh, (m ** (m' ** (ys, ns, refl)))) =
    (S m ** (m' ** ((x ** oh)::ys, ns, refl)))
  partition' p (x :: xs) | (Right oh, (m ** (m' ** (ys, ns, refl)))) =
    (m ** (S m' ** (ys, (x ** oh)::ns, sym (plusSuccRightSucc m m'))))

, , , , . , .

+10

Source: https://habr.com/ru/post/1539309/


All Articles