Dependent types: providing global properties in inductive types

I have the following inductive type MyVec:

import Data.Vect

data MyVec: {k: Nat} -> Vect k Nat -> Type where
  Nil: MyVec []
  (::): {k, n: Nat} -> {v: Vect k Nat} -> Vect n Nat -> MyVec v -> MyVec (n :: v)

-- example:
val: MyVec [3,2,3]
val = [[2,1,2], [0,2], [1,1,0]]

That is, the type determines the lengths of all vectors inside a MyVec.

The problem is that it valwill have k = 3( k- the number of vectors inside a MyVec), but ctor ::does not know this fact. First he will build MyVecwith k = 1, then with 2and finally with help 3. This makes it impossible to define constraints based on the finite form of the value.

For example, I cannot limit values โ€‹โ€‹strictly less k. Adopting Vectof Fin (S k)instead of Vectof Natexcludes some valid values, since the last vectors (the first inserted ctor) will "know" a lower value k, and thus more stringent restrictions.

Or, another example, I cannot force the following restriction: the vector at position I cannot contain the number i. Since the final position of the vector in the container is not known to ctor (it would be automatically known whether the final value of k is known).

So the question is, how can I apply such global properties?

+4
source share
1 answer

( ) , , .

data

< k

k. Vect of Fin (S k) Vect of Nat ...

, MyVect Vect n (Fin (S k)) .

, , MyVect , .

data MyVec: (A : Type) -> {k: Nat} -> Vect k Nat -> Type where
  Nil: {A : Type} -> MyVec A []
  (::): {A : Type} -> {k, n: Nat} -> {v: Vect k Nat} -> Vect n A -> MyVec A v -> MyVec A (n :: v)

val : MyVec (Fin 3) [3,2,3]
val = [[2,1,2], [0,2], [1,1,0]]

k MyVec, " k .

i i

, i, .

, data . , . index. A . , , , .

data MyVec': (A : Nat -> Type) -> (index : Nat) -> {k: Nat} -> Vect k Nat -> Type where
  Nil: {A : Nat -> Type} -> {index : Nat} -> MyVec' A index []
  (::): {A : Nat -> Type} -> {k, n, index: Nat} -> {v: Vect k Nat} ->
        Vect n (A index) -> MyVec' A (S index) v -> MyVec' A index (n :: v)

val : MyVec' (\n => (m : Nat ** (n == m = False))) 0 [3,2,3]
val = [[(2 ** Refl),(1 ** Refl),(2 ** Refl)], [(0 ** Refl),(2 ** Refl)], [(1 ** Refl),(1 ** Refl),(0 ** Refl)]]

, - data, .

< k

, , , < k, , .

wf : (final_length : Nat) -> {k : Nat} -> {v : Vect k Nat} -> MyVec v -> Bool
wf final_length [] = True
wf final_length (v :: mv) = isNothing (find (\x => x >= final_length) v) && wf final_length mv

val : (mv : MyVec [3,2,3] ** wf 3 mv = True)
val = ([[2,1,2], [0,2], [1,1,0]] ** Refl)

i i

, , , , .

wf : (index : Nat) -> {k : Nat} -> {v : Vect k Nat} -> MyVec v -> Bool
wf index [] = True
wf index (v :: mv) = isNothing (find (\x => x == index) v) && wf (S index) mv

val : (mv : MyVec [3,2,3] ** wf 0 mv = True)
val = ([[2,1,2], [0,2], [1,1,0]] ** Refl)
+4

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


All Articles