Prime numbers in Idris - idris

In idris 0.9.17.1,
with inspiration from https://wiki.haskell.org/Prime_numbers,
I've written the following code for generating prime numbers
module Main
concat: List a -> Stream a -> Stream a
concat [] ys = ys
concat (x :: xs) ys = x :: (concat xs ys)
generate: (Num a, Ord a) => (start:a) -> (step:a) -> (max:a) -> List a
generate start step max = if (start < max) then start :: generate (start + step) step max else []
mutual
sieve: Nat -> Stream Int -> Int -> Stream Int
sieve k (p::ps) x = concat (start) (sieve (k + 1) ps (p * p)) where
fs: List Int
fs = take k (tail primes)
start: List Int
start = [n | n <- (generate (x + 2) 2 (p * p - 2)), (all (\i => (n `mod` i) /= 0) fs)]
primes: Stream Int
primes = 2 :: 3 :: sieve 0 (tail primes) 3
main:IO()
main = do
printLn $ take 10 primes
In the REPL, if I write take 10 primes, the REPL correctly shows [2, 3, 5, 11, 13, 17, 19, 29, 31, 37] : List Int
But if I try :exec, nothing happen and if I try to compile ans execute the program I get Segmentation fault: 11
Can someone help me to debug this problem ?

Your concat function can be made lazy to fix this. Just change its type to
concat : List a -> Lazy (Stream a) -> Stream a
This will do it.
Note:
To get all primes, change the < inside the generate function into <=
(Currently some are missing, e.g. 7 and 23).

Related

Proof inside nested constructor of recursive type

I am having some trouble with the code below. Essentially I want to create a slice type. The motivation comes from Python, where a slice is [start:end:step], used for slicing a sublist out of a list. This is conceptually the same as a sequence of indices [start, start+step, start+2*step, ..., end].
The way I've tried to capture it is Slice n can be applied to a Vect (n+m) a. The basic constructor FwdS will create a slice with a non-zero step (proof stepNZ). The SLen constructor will increment an existing slice's Vect size requirement by its step (computed using stepOf). Similarly SStart increments a slice's Vect size requirement by 1.
Then the final value conceptually corresponds to:
start := # of SStart in slice
stop := start + (# of SLen) * step
step := constructor argument in FwdS
If the slice is [start:stop:step].
mutual
data Slice : Nat -> Type where
FwdS : (step : Nat) -> {stepNZ : Not (step = Z)} -> Slice Z
SLen : (x : Slice len) -> Slice (len + (stepOf x))
SStart : Slice len -> Slice (S len)
stepOf : Slice n -> Nat
stepOf (FwdS step) = step
stepOf (SLen slice) = stepOf slice
stepOf (SStart slice) = stepOf slice
length : Slice n -> Nat
length (FwdS step ) = Z
length (SLen slice) = let step = stepOf slice
len = length slice
in len + step
length (SStart slice) = length slice
select : (slice: Slice n) -> Vect (n+m) a -> Vect (length slice) a
select (FwdS step) xs = []
select (SStart slice) (x :: xs) = select slice xs
select (SLen slice) (xs) = ?trouble
The trouble is in the last pattern. I'm not sure what the issue is - if I try to case split on xs I get both [] and (_::_) impossible. Ideally I'd like to have that case read something like this:
select (SLen slice) (x :: xs) = let rec = drop (stepOf slice) (x::xs)
in x :: (select slice rec)
and have Idris recognize that if the first argument is an SLen constructor, the second argument cannot be []. My intuition is that at the SLen level, Idris does not understand it already has a proof that stepOf slice is not Z. But I'm not sure how to test that idea.
My intuition is that at the SLen level, Idris does not understand it already has a proof that stepOf slice is not Z.
You are right. With :t trouble you see that the compiler doesn't have enough information to infer that (plus (plus len (stepOf slice)) m) is not 0.
a : Type
m : Nat
len : Nat
slice : Slice len
xs : Vect (plus (plus len (stepOf slice)) m) a
--------------------------------------
trouble : Vect (plus (length slice) (stepOf slice)) a
You would have to solve two problems: get a proof that stepOf slice is S k for some k like getPrf : (x : Slice n) -> (k ** stepOf x = (S k)), then rewrite Vect (plus (plus len (stepOf slice)) m) a to something like Vect (S (plus k (plus len m))) a so the compiler can at least know that this xs is not empty. But it doesn't get easier from thereon. :-)
Basically whenever you have a function where you use functions in the arguments, you probably can rewrite those informations into the type. Like select with length slice or SLen with stepOf x. Here is an example implementation:
data Slice : (start : Nat) -> (len : Nat) -> (step : Nat) -> (cnt : Nat) -> Type where
FwdS : (step : Nat) -> Slice Z Z step Z
SLen : Slice Z len step cnt -> Slice Z (S step + len) step (S cnt)
SStart : Slice start len step cnt -> Slice (S start) len step cnt
You gain a lot from this: you can access the parameters len and step directly without proving the functions length and stepOf first. Also you can have better control about your allowed data. For example, in your definiton SLen $ SStart $ SLen $ SStart $ FwdS 3 would have been valid, mixing steps and start increments.
select could look like this:
select : Slice start len step cnt -> Vect (start + len + m) a -> Vect cnt a
select (FwdS k) xs = []
select (SStart s) (x :: xs) = select s xs
select (SLen s) [] impossible
select (SLen s {step} {len} {cnt}) (x::xs) {m} {a} =
let is = replace (sym $ plusAssociative step len m) xs {P=\t => Vect t a} in
(x :: select s (drop step is))
If you want an exercise with proving, you could try to implement select : Slice start len step cnt -> Vect (len + start + m) a -> Vect cnt a, so switching start + len.
And getting two elements starting at 1 in steps of 4:
> select (SStart $ SLen $ SLen $ FwdS 3) [0,1,2,3,4,5,6,7,8,9]
[1, 5] : Vect 2 Integer

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

Hofstadter Female and Male sequences in SML

This is my first SML program. I am trying to write a function that returns the first number to the nth number of Hofstadter's Female or Male sequence in list form. What I have so far is:
val m = fn (n) => if n = 0 then 1 :: [] else m f (n - 1);
val f = fn (n) => if n = 0 then 0 :: [] else f m (n - 1);
You can learn about the sequence here:
https://en.wikipedia.org/wiki/Hofstadter_sequence#Hofstadter_Female_and_Male_sequences
The error that I am getting is:
[opening sequence.sml]
sequence.sml:1.49 Error: unbound variable or constructor: f
sequence.sml:1.47-1.58 Error: operator is not a function [tycon mismatch]
operator: int list
in expression:
(m <errorvar>) (n - 1)
val it = () : unit
How can I correct this?
I ended up taking this approach:
fun
m (n) = if n = 0 then 0 else n - (f (m (n - 1)))
and
f (n) = if n = 0 then 1 else n - (m (f (n - 1)));
val seq = fn n => List.tabulate((n), f);
It is quite slow. If anybody has a faster version, then I'd love to see it.
Although you have already fixed them, there were two problems with your original approach:
Function application is left-associative in SML so m f (n - 1) was being interpreted as (m f) (n - 1), not the desired m (f (n - 1)). You can fix this by explicitly specifying the bracketing m (f (n - 1)).
To be able to call f from m and m from f, you need to use the keyword fun instead of val on the first declaration (to make the function recursive), and the keyword and instead of fun or val on the second declaration (to make the function mutually recursive with the first function). This would look like
fun f n = ... (* I can call f or m from here! *)
and m n = ... (* I can call f or m from here! *)
To make it faster, you can memoize! The trick is to make f and m take as arguments memoized versions of themselves.
(* Convenience function: Update arr[i] to x, and return x. *)
fun updateAndReturn arr i x = (Array.update (arr, i, SOME x); x)
(*
* Look up result of f i in table; if it's not found, calculate f i and
* store in the table. The token is used so that deeper recursive calls
* to f can also try to store in the table.
*)
fun memo table f token i =
case Array.sub (table, i)
of NONE => updateAndReturn table i (f token i)
| SOME x => x
(*
* Given f, g, and n : int, returns a tuple (f', g') where f' and g' are memoized
* versions of f and g, respectively. f' and g' are defined only on the domain
* [0, n).
*)
fun memoizeMutual (f, g) n =
let
val fTable = Array.array (n, NONE)
val gTable = Array.array (n, NONE)
fun fMemo i = memo fTable f (fMemo, gMemo) i
and gMemo i = memo gTable g (gMemo, fMemo) i
in
(fMemo, gMemo)
end
fun female _ 0 = 1
| female (f, m) n = n - m (f (n - 1))
fun male _ 0 = 0
| male (m, f) n = n - f (m (n - 1))
fun hofstadter upTo =
let
val (male', female') = memoizeMutual (male, female) upTo
in
(List.tabulate (upTo, male'), List.tabulate (upTo, female'))
end
I renamed f and m to female and male. The memoized fMemo and gMemo are threaded through female and male by memoizeMutual. Interestingly, if we call male', then results for both male' and female' are memoized.
To confirm it's indeed faster, try evaluating hofstadter 10000. It's much faster than the forever that your version would take.
As a final note, the only recursive functions are fMemo and gMemo. Every other function I wrote could be written as an anonymous function (val memoizeMutual = fn ..., val female = fn ..., etc.), but I chose not to do so because the syntax for writing recursive functions is much more compact in SML.
To generalize this, you could replace the array version of memoizing with something like a hash table. Then we wouldn't have to specify the size of the memoization up front.

How does "There" work in the idris tutorial, page 11, section 3.4.4?

Here is the example from the tutorial, slightly modified for simplicity:
data Vect : Nat -> (b:Type) -> Type where
Nil : Vect Z a
(::) : a -> Vect k a -> Vect (S k) a
data Elem : a -> Vect n a -> Type where
Here : {x:a} -> {xs:Vect n a} -> Elem x (x :: xs)
There : {x,y:a} -> {xs:Vect n a} -> Elem x xs -> Elem x (y :: xs)
testVec : Vect 4 Int
testVec = 3 :: 4 :: 5 :: 6 :: Nil
inVect : Elem 4 testVec
inVect = There Here
I can't understand how There verifies that the value is correct.
As far as I understand it, There works like a function, so it takes the
element of type Here, which when filling in the holes, corresponds to Elem 3 testVec, then sets the first value of testVec to y, and the rest to xs. But since, y isn't used anywhere, I would except this not to cause any restriction.
However, when I try
inVectBroken : Elem 2 testVec
inVectBroken = There Here
I get an error:
When checking an application of constructor There:
Type mismatch between
Elem x (x :: xs) (Type of Here)
and
Elem 2 [4, 5, 6] (Expected type)
Specifically:
Type mismatch between
2
and
4
Can someone explain to me how the above code works (magically?) to restrict There to the tail of Vect?
Here 4 (x :: xs) is a proof that 4 is at the head of (x :: xs), so x = 4. There takes a proof Elem 4 xs that 4 is somewhere in xs and so proofs Elem 4 (y :: xs), that 4 is still somewhere down a extended list. That is where the y goes to. It does not matter what y actually is, it just allows to extend the proof to larger lists. For example:
in1 : Elem 4 (4 :: Nil)
in1 = Here
in2 : Elem 4 (3 :: 4 :: Nil)
in2 = There in1
in3 : Elem 4 (8 :: 4 :: Nil)
in3 = There in1
By the types you see that not the element 4 changes throughout the proof but the list.

Haskell, function works when using numbers, but not with variables

I'm using ghci and I'm having a problem with a function for getting the factors of a number.
The code I would like to work is:
let factors n = [x | x <- [1..truncate (n/2)], mod n x == 0]
It doesn't complain when I then hit enter, but as soon as I try to use it (with 66 in this case) I get this error message:
Ambiguous type variable 't0' in the constraints:
(Integral t0)
arising from a use of 'factors' at <interactive>:30:1-10
(Num t0) arising from the literal '66' at <interactive>:30:12-13
(RealFrac t0)
arising from a use of 'factors' at <interactive:30:1-10
Probable fix: add a type signature that fixes these type variable(s)
In the expression: factors 66
In the equation for 'it': it = factors 66
The following code works perfectly:
let factorsOfSixtySix = [x | x <- [1..truncate (66/2)], mod 66 x == 0]
I'm new to haskell, and after looking up types and typeclasses, I'm still not sure what I'm meant to do.
Use div for integer division instead:
let factors n = [x | x <- [1.. n `div` 2], mod n x == 0]
The problem in your code is that / requires a RealFrac type for n while mod an Integral one. This is fine during definition, but then you can not choose a type which fits both constraints.
Another option could be to truncate n before using mod, but is more cumbersome. After all, you do not wish to call factors 6.5, do you? ;-)
let factors n = [x | x <- [1..truncate (n/2)], mod (truncate n) x == 0]
If you put a type annotation on this top-level bind (idiomatic Haskell), you get different, possibly more useful error messages.
GHCi> let factors n = [x | x <- [1..truncate (n/2)], mod n x == 0]
GHCi> :t factors
factors :: (Integral t, RealFrac t) => t -> [t]
GHCi> let { factors :: Double -> [Double]; factors n = [x | x <- [1..truncate (n/2)], mod n x == 0]; }
<interactive>:30:64:
No instance for (Integral Double) arising from a use of `truncate'
Possible fix: add an instance declaration for (Integral Double)
In the expression: truncate (n / 2)
In the expression: [1 .. truncate (n / 2)]
In a stmt of a list comprehension: x <- [1 .. truncate (n / 2)]
GHCi> let { factors :: Integer -> [Integer]; factors n = [x | x <- [1..truncate (n/2)], mod n x == 0]; }
<interactive>:31:66:
No instance for (RealFrac Integer) arising from a use of `truncate'
Possible fix: add an instance declaration for (RealFrac Integer)
In the expression: truncate (n / 2)
In the expression: [1 .. truncate (n / 2)]
In a stmt of a list comprehension: x <- [1 .. truncate (n / 2)]
<interactive>:31:77:
No instance for (Fractional Integer) arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Integer)
In the first argument of `truncate', namely `(n / 2)'
In the expression: truncate (n / 2)
In the expression: [1 .. truncate (n / 2)]
I am new to Haskell so please forgive my courage to come up with an answer here but recently i have done this as follows;
factors :: Int -> [Int]
factors n = f' ++ [n `div` x | x <- tail f', x /= exc]
where lim = truncate (sqrt (fromIntegral n))
exc = ceiling (sqrt (fromIntegral n))
f' = [x | x <- [1..lim], n `mod` x == 0]
I believe it's more efficient. You will notice if you do like;
sum (factors 33550336)