Auto does not find a value it should be able to find - idris

Why does I confuse auto? Deleting it makes everything work.
module Main
import Data.Vect
%default total
data LessThan : String -> String -> Type where
D : (x < x' = True) -> LessThan x x'
I : LessThan x x' -> LessThan x' x'' -> LessThan x x'' -- Deleting this line fixes the error
data OrderedStringVect : Vect n String -> Type where
Nil : OrderedStringVect []
OAddF : (x : String) -> OrderedStringVect [] -> OrderedStringVect [x] -- Adding the first element does not require a LT from
OAddO : (x : String) -> OrderedStringVect (x'::xs) -> {auto p : LessThan x x'} -> OrderedStringVect (x :: x' :: xs) -- Adding another element does
data InsertProof : String -> Vect n String -> Type where
IPF : InsertProof n [] -- There is no first element
IPH : LessThan n n' -> InsertProof n (n' :: ns) -- Less the the first element
IPL : LessThan n' n -> InsertProof n ns -> InsertProof n (n' :: ns) -- Greater than the first element
-- Eq is not allowed
insertT : (n : String) -> (ns : Vect m String) -> {auto p : InsertProof n ns} -> Vect (S m) String
insertT {p = IPF} n [] = n :: []
insertT {p = IPH _} n (n'::ns) = n :: n' :: ns
insertT {p = IPL _ _} n (n'::ns) = n' :: insertT n ns
(::) : (n : String) -> OrderedStringVect ns -> {auto p : InsertProof n ns} -> OrderedStringVect (insertT {p=p} n ns)
(::) {p = IPF} n Nil = OAddF n Nil
(::) {p = IPH _} n (OAddF n' []) = OAddO n (OAddF n' [])
(::) {p = IPH _} n (OAddO n' ns) = OAddO n (OAddO n' ns)
(::) {p = IPL _ IPF} n (OAddF n' Nil) = OAddO n' (OAddF n Nil)
(::) {p = IPL _ (IPH _)} n (OAddO n' ns) = OAddO n' (OAddO n ns)
(::) {p = IPL _ (IPL _ _)} n (OAddO n' ns) = OAddO n' (n :: ns)
test : with Main ["foo", "bar", "biz"] = ["bar", "biz", "foo"] -- Prove order does not matter
test = Refl
Error:
Type checking ./main7.idr
main7.idr:32:58-60:When checking right hand side of Main.:: with expected type
OrderedStringVect (insertT n (n' :: x' :: xs))
When checking argument p to Main.:::
Can't find a value of type
InsertProof n (x' :: xs)
main7.idr:34:6:When checking type of Main.test:
Can't disambiguate name: Prelude.List.::, Main.::, Prelude.Stream.::, Data.Vect.::
Edit: I have decided to do something completely different so I no longer need the answer, but would still like to know.

Related

Hole with Delay in type. How to prove?

I was trying to prove that replicate1 works correctly by showing that all elements of replicate1 n x are x:
all1 : (p : a -> Bool) -> List a -> Bool
all1 p [] = True
all1 p (x :: xs) = p x && all1 p xs
replicate1 : (n: Nat) -> a -> List a
replicate1 Z x = [x]
replicate1 (S k) x = x :: replicate1 k x
all_replicate_is_x : Eq a => {x: a} -> all1 (== x) (replicate1 n x) = True
all_replicate_is_x {n = Z} = ?hole
all_replicate_is_x {n = (S k)} = ?all_replicate_is_x_rhs_2
The base case hole is
Test.hole [P]
`-- a : Type
constraint : Eq a
x : a
-----------------------------------------
Test.hole : x == x && Delay True = True
How to prove this?

How can I get Idris to unmap a vector in order to infer a type?

I have the following working function:
unMaybe : (t : Type) -> {auto p : t = Maybe x} -> Type
unMaybe {x} _ = x
This function works fine:
> unMaybe (Maybe Int)
Int
I also have another similar function:
unMaybesA : (ts : Vect n Type) -> {xs : Vect n Type} -> {auto p : map Maybe xs = ts} -> Vect n Type
unMaybesA {xs} _ = xs
Unfortunately the following fails:
> unMaybesA [Maybe Int, Maybe String]
(input):1:1-35:When checking argument p to function Main.unMaybesA:
Can't find a value of type
Data.Vect.Vect n implementation of Prelude.Functor.Functor, method map Maybe
xs =
[Maybe Int, Maybe String]
But the following works:
> unMaybesA {xs=[_,_]} [Maybe Int, Maybe String]
[Int, String]
Is the a way to get Idris to automatically do {xs=[_,_]} with however many _ the vector has?
unMaybesB : (ts : Vect n Type) -> {auto p : (xs : Vect n Type ** map Maybe xs = ts)} -> Vect n Type
unMaybesB {p} _ = fst p
Possibly by using an elaborator script to automatically fill p in the function above?
I have the outline of an elab script below. I just need to figure out how to generate n, ts, and xs from the goal.
helper1 : Vect n Type -> Vect n Type -> Type
helper1 ts xs = (map Maybe xs) = ts
unMaybesC : (ts : Vect n Type) -> {auto p : DPair (Vect n Type) (helper1 ts)} -> Vect n Type
unMaybesC {p} _ = fst p
helper2 : (n : Nat) -> (ts : Vect n Type) -> (xs : Vect n Type) -> helper1 ts xs -> DPair (Vect n Type) (helper1 ts)
helper2 _ _ xs p = MkDPair xs p
q : Elab ()
q = do
let n = the Raw `(2 : Nat)
let ts = the Raw `(with Vect [Maybe String, Maybe Int])
let xs = the Raw `(with Vect [String, Int])
fill `(helper2 ~n ~ts ~xs Refl)
solve
qC : Vect 2 Type
qC = unMaybesC {p=%runElab q} [Maybe String, Maybe Int]
map Maybe xs = ts seems idiomatic, but is quite difficult. If you want to auto search for a non-simple proof, write an explicit proof type. Then the proof search will try the constructors and is guided in the right direction.
data IsMaybes : Vect n Type -> Vect n Type -> Type where
None : IsMaybes [] []
Then : IsMaybes xs ms -> IsMaybes (t :: xs) (Maybe t :: ms)
unMaybes : (ts : Vect n Type) -> {xs : Vect n Type} -> {auto p : IsMaybes xs ts} -> Vect n Type
unMaybes ts {xs} = xs
And with this:
> unMaybes [Maybe Nat, Maybe Int, Maybe (Maybe String)]
[Nat, Int, Maybe String] : Vect 3 Type

Inf value is automatically forced after pattern matching

Let's say we have an infinite list:
data InfList : Type -> Type where
(::) : (value : elem) -> Inf (InfList elem) -> InfList elem
And we want to have finite number of its elements:
getPrefix : (count : Nat) -> InfList a -> List a
getPrefix Z _ = []
getPrefix (S k) (value :: xs) = value :: getPrefix k (?rest)
So, what is left:
a : Type
k : Nat
value : a
xs : InfList a
--------------------------------------
rest : InfList a
It turned out that after pattern matching xs become InfList a instead of Inf (InfList a).
Is there a way to have xs delayed?
It seems to be delayed anyway.
If you execute :x getPrefix 10 one with
one : InfList Int
one = 1 :: one
you get 1 :: getPrefix 9 (1 :: Delay one)
I can't find it anymore in the documentation but idris seems to insert Delay automatically.
Just try to add Delay constructor manually. It's removed implicitly.
getPrefix : (count : Nat) -> InfList a -> List a
getPrefix Z _ = []
getPrefix (S k) (value :: Delay xs) = value :: getPrefix k xs

In Idris, how to write a "vect generator" function that take a function of index in parameter

I'm trying to write in Idris a function that create a Vect by passing the size of the Vect and a function taking the index in parameter.
So far, I've this :
import Data.Fin
import Data.Vect
generate: (n:Nat) -> (Nat -> a) ->Vect n a
generate n f = generate' 0 n f where
generate': (idx:Nat) -> (n:Nat) -> (Nat -> a) -> Vect n a
generate' idx Z f = []
generate' idx (S k) f = (f idx) :: generate' (idx + 1) k f
But I would like to ensure that the function passed in parameter is only taking index lesser than the size of the Vect.
I tried that :
generate: (n:Nat) -> (Fin n -> a) ->Vect n a
generate n f = generate' 0 n f where
generate': (idx:Fin n) -> (n:Nat) -> (Fin n -> a) -> Vect n a
generate' idx Z f = []
generate' idx (S k) f = (f idx) :: generate' (idx + 1) k f
But it doesn't compile with the error
Can't convert
Fin n
with
Fin (S k)
My question is : is what I want to do possible and how ?
The key idea is that the first element of the vector is f 0, and for the tail, if you have k : Fin n, then FS k : Fin (S n) is a "shift" of the finite number that increments its value and its type at the same time.
Using this observation, we can rewrite generate as
generate : {n : Nat} -> (f : Fin n -> a) -> Vect n a
generate {n = Z} f = []
generate {n = S _} f = f 0 :: generate (f . FS)
Another possibility is to do what #dfeuer suggested and generate a vector of Fins, then map f over it:
fins : (n : Nat) -> Vect n (Fin n)
fins Z = []
fins (S n) = FZ :: map FS (fins n)
generate' : {n : Nat} -> (f : Fin n -> a) -> Vect n a
generate' f = map f $ fins _
Proving generate f = generate' f is left as en exercise to the reader.
Cactus's answer appears to be about the best way to get what you asked for, but if you want something that can be used at runtime, it will be quite inefficient. The essential reason for this is that to weaken a Fin n to a Fin n+m requires that you completely deconstruct it to change the type of its FZ, and then build it back up again. So there can be no sharing at all between the Fin values produced for each vector element. An alternative is to combine a Nat with a proof that it is below a given bound, which leads to the possibility of erasure:
data NFin : Nat -> Type where
MkNFin : (m : Nat) -> .(LT m n) -> NFin n
lteSuccLeft : LTE (S n) m -> LTE n m
lteSuccLeft {n = Z} prf = LTEZero
lteSuccLeft {n = (S k)} {m = Z} prf = absurd (succNotLTEzero prf)
lteSuccLeft {n = (S k)} {m = (S j)} (LTESucc prf) = LTESucc (lteSuccLeft prf)
countDown' : (m : Nat) -> .(m `LTE` n) -> Vect m (NFin n)
countDown' Z mLTEn = []
countDown' (S k) mLTEn = MkNFin k mLTEn :: countDown' k (lteSuccLeft mLTEn)
countDown : (n : Nat) -> Vect n (NFin n)
countDown n = countDown' n lteRefl
countUp : (n : Nat) -> Vect n (NFin n)
countUp n = reverse $ countDown n
generate : (n : Nat) -> (NFin n -> a) -> Vect n a
generate n f = map f (countUp n)
As in the Fin approach, the function you pass to generate does not need to work on all naturals; it only needs to handle ones less than n.
I used the NFin type to explicitly indicate that I want the LT m n proof to be erased in all cases. If I didn't want/need that, I could just use (m ** LT m n) instead.

How do I provide an implicit argument explicitly?

Suppose I have a function with this signature:
myNatToFin : (m : Nat) -> (n : Nat) -> { auto p : n `GT` m } -> Fin n
I try to apply it like this myNatToFin k (S k) in the body of another function and I get the error:
Can't solve goal
GT (S k) k
So, I believe I have to explicitly pass a proof that GT (S k) k, but I have no idea how to do this. How can I explicitly pass the implicit proof argument so that this compiles?
You can give explicit arguments for implicit parameters by enclosing them in braces and prefixing with the parameter name, like {p = someExpression foo}.
Full example:
import Data.Fin
myNatToFin : (m : Nat) -> (n : Nat) -> { auto p : n `GT` m } -> Fin n
myNatToFin m n = ?x -- See https://stackoverflow.com/questions/29908731/
lteRefl : LTE n n
lteRefl {n = Z} = LTEZero
lteRefl {n = S _} = LTESucc lteRefl
foo : (k : Nat) -> Fin (S k)
foo k = myNatToFin k (S k) {p = LTESucc lteRefl}