How to prove statements of the form forall x. phi x in F*? - fstar

I have just started learning F*, going through the tutorial. One of the exercises there is to prove that the reverse function on lists is injective.
Since this follows from the fact that involutions are injective I would like to express that fact as a lemma in F*. To do that I define
let is_involutive f = forall x. (f (f x) == x)
let is_injective f = forall x y. (f x == f y) ==> x == y
Is this the right way to define the notion of f being involutive or injective in F*?
Then I state the lemma
val inv_is_inj: #a:eqtype -> a -> f:(a->a) ->
Lemma (requires (is_involutive f)) (ensures(is_injective f))
Informally the proof can be written as
{ fix (x:a) (y:a)
assume (f x == f y)
then have (f (f x) == f (f y))
with (is_involutive f) have (x == y)
} hence (forall (x:a) (y:a). f x == f y ==> x == y)
then have (is_injective f)
How do I express such proof in F*?
In general, what F* language constructs can be used to prove statements of the form forall (x:a). phi x, where phi is a predicate on a type a?

Related

Composition using foldr SML

Is there any way to do something like a(b(c(5))) from a variable that contains the functions?
The code would be something like that:
val a = fn x => x + 10
val b = fn x => x * x
val c = fn x => (x - 2) * 3
val fs = [a, b, c]
You can apply op to the composition operator o so that it can be used as a function, and then use that function with foldr to fold the list of functions down to a single function. Use the identity function as an initial value.
Thus, foldr (op o) identity [a, b, c] is equivalent to a o (b o (c o identity)), where identity is the identity function:
fun identity x = x;
Using the posted definitions for a, b, c, and fs it's not too bad to write OP example as a one-liner:
- (foldr (op o) (fn x => x) fs) 5;
val it = 91 : int
- a(b(c 5));
val it = 91 : int
It's a bit easier if identity has been defined, but even nicer to define a higher-order function to abstract this away:
fun composeList fs = foldr (op o) (fn x => x) fs;
- composeList fs 5;
val it = 91 : int

Connecting all elements in list with infix operator

So I have a list lets say [t, f, f, t, f] and an infix operator <==>. I want to connect the elements so the end result will look like this t <==> f <==> f <==> t <==> f . The problem that I am having though is that i get this result t <==> (f <==> (f <==> (t <==> f))). I know why this is happening because the resursion returns all previous elements but I have no idea how to fix it.
This is my code:
fun connect(l) =
case l of
x::[] => x
| x::xs => x1 <==> connect(xs);
the end result will look like this t <==> f <==> f <==> t <==> f.
problem is that i get this result t <==> (f <==> (f <==> (t <==> f)))
x <==> y <==> z could mean either (x <==> y) <==> z or x <==> (y <==> z).
If it is a problem that you fold to one side, try folding to the other:
fun connectLeft (x::xs) = foldl (op <==>) x xs
fun connectRight (x::xs) = foldr (op <==>) x xs
You can see how foldl and foldr are implemented.
Or you can see the illustration of folds as structural transformations (Wikipedia).
Edit: Assuming x <==> y <==> z means (x <==> y) && (y <==> z):
fun connect [] = ?
| connect [x] = ?
| connect [x,y] = x <==> y
| connect (x :: y :: rest) =
(x <==> y) && connect (y :: rest)
&& is not the name of SML's built-in logical and-operator, which is called andalso. If x <==> y returns a bool, then perhaps you mean to use andalso here.
Since connect supposedly returns either a bool or some user-defined truthy value, then maybe connect [x] = x, but maybe not.
In any case, connect [] should be considered: Is there a good default here, so that the function does not crash on empty lists?
If you want to write this using list combinators (like map, foldl, etc.) instead of manual recursion, what you can do is:
Convert the input list into a list of pairs, so [x, y, z] becomes [(x, y), (y, z)]. There is an SML function called zip, hiding away in the library ListPair... a few examples that might hint at how to do this:
ListPair.zip [x1,x2,x3] [y1,y2,y3] = [(x1,y1), (x2,y2), (x3,y3)]
ListPair.zip [x1,x2,x3] [x1,x2,x3] = [(x1,x1), (x2,x2), (x3,x3)]
ListPair.zip [x1,x2,x3] [y2,y3] = [(x1,y2), (x2,y3)]
Call map (op <==>) over the list of pairs.
Fold over the result with some && operator.

Idris - Define a primes type

I am learning Idris and as a personal exercise, I would like to implement a Primes type, consisting of all the prime numbers.
Is there a way in idris to define a new type starting from a type and a property, which will select all the elements of the starting type for which the property holds true? In my case, is there a way to define Primes as the set of Nat such that n <= p and n|p => n=1 or n=p?
If this is not possible, should I define prime numbers constructing them inductively using some kind of sieve?
I like copumpkin's Agda definition of Prime, which looks like this in Idris:
data Divides : Nat -> Nat -> Type where
MkDivides : (q : Nat) ->
n = q * S m ->
Divides (S m) n
data Prime : Nat -> Type where
MkPrime : GT p 1 ->
((d : Nat) -> Divides d p -> Either (d = 1) (d = p))
-> Prime p
Read as "if p is divisible by d, then d must be 1 or p" - a common definition for primality.
Proving this by hand for a number can be pretty tedious:
p2' : (d : Nat) -> Divides d 2 -> Either (d = 1) (d = 2)
p2' Z (MkDivides _ _) impossible
p2' (S Z) (MkDivides Z Refl) impossible
p2' (S Z) (MkDivides (S Z) Refl) impossible
p2' (S Z) (MkDivides (S (S Z)) Refl) = Left Refl
p2' (S Z) (MkDivides (S (S (S _))) Refl) impossible
p2' (S (S Z)) (MkDivides Z Refl) impossible
p2' (S (S Z)) (MkDivides (S Z) Refl) = Right Refl
p2' (S (S Z)) (MkDivides (S (S _)) Refl) impossible
p2' (S (S (S _))) (MkDivides Z Refl) impossible
p2' (S (S (S _))) (MkDivides (S _) Refl) impossible
p2 : Prime 2
p2 = MkPrime (LTESucc (LTESucc LTEZero)) p2'
It's also very involved to write a decision procedure for this. That'll be a big exercise! You'll probably find the rest of the definitions useful for that:
https://gist.github.com/copumpkin/1286093

SML Match Redundant Error

Im writing some code for an insertion sort in SML. Here it is.
fun compare(x:real, y:real, F) = F(x, y);
fun isEqual(x:real, y:real) = ((x <= y) andalso (x >= y));
fun rinsert(x: real, L: real list, F) = [x]
|rinsert(x, (y::ys), F) =
if isEqual(x, y) then rinsert (x, ys, F)
else if compare(x, y, F) then x::y::ys
else y::(rinsert (x, ys, F));
fun rinsort(L : real list, F) = []
|rinsort(x::xs, F) = rinsert(x, (rinsort (xs, F), F);
For whatever reason i keep coming up with this error
- val compare = fn : real * real * (real * real -> 'a) -> 'a
val isEqual = fn : real * real -> bool
stdIn:4.6-8.42 Error: match redundant
(x,L,F) => ...
--> (x,y :: ys,F) => ...
I understand what it's saying, that I've got a repetitive line somewhere, but I'm not sure where the problem could be.
The first line of rinsert has plain variables for each argument, so matches everything. Consequently, the second case is never reached. Same for rinsort.
To fix this, you'll need to replace the L parameter in both with the pattern [] for the empty list.

Haskell infinite recursion in list comprehension

I am trying to define a function that accepts a point (x,y) as input, and returns an infinite list corresponding to recursively calling
P = (u^2 − v^2 + x, 2uv + y)
The initial values of u and v are both 0.
The first call would be
P = (0^2 - 0^2 + 1, 2(0)(0) + 2) = (1,2)
Then that resulting tuple (1,2) would be the next values for u and v, so then it would be
P = (1^2 - 2^2 + 1, 2(1)(2) + 2) = (-2,6)
and so on.
I'm trying to figure out how to code this in Haskell. This is what I have so far:
o :: Num a =>(a,a) -> [(a,a)]
o (x,y) = [(a,b)| (a,b)<- [p(x,y)(x,y)]]
where p(x,y)(u,v) = ((u^2)-(v^2)+x,(2*u*v)+y)
I'm really not sure how to make this work. Any help would be appreciated!
Let's first ignore the exact question you have, and focus on getting the loop working. What you want, essentially, is to have something that takes some initial value iv (namely, (0, 0) for (u, v)), and returns the list
f iv : f (f iv) : f (f (f iv)) : f (f (f (f iv))) : ...
for some function f (constructed from your p and (x, y)). Moreover, you want the result to reuse the previously computed elements of the list. If I would write a function myself that does this, it might looke like this (but maybe with some different names):
looper :: (a -> a) -> a -> [a]
looper f iv = one_result : more_results
where
one_result = f iv
more_results = looper f one_result
But, of course, I would first look if a function with that type exists. It does: it's called Data.List.iterate. The only thing it does wrong is the first element of the list will be iv, but that can be easily fixed by using tail (which is fine here: as long as your iteration function terminates, iterate will always generate an infinite list).
Let's now get back to your case. We established that it'll generally look like this:
o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate f iv)
where
f (u, v) = undefined
iv = undefined
As you indicated, the initial value of (u, v) is (0, 0), so that's what our definition of iv will be. f now has to call p with the (x, y) from o's argument and the (u, v) for that iteration:
o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate f iv)
where
f (u, v) = p (x, y) (u, v)
iv = (0, 0)
p = undefined
It's as simple as that: the (x, y) from o's definition is actually in scope in the where-clause. You could even decide to merge f and p, and end up with
o :: Num a => (a, a) -> [(a, a)]
o (x, y) = tail (iterate p iv)
where
iv = (0, 0)
p (u, v) = (u^2 - v^2 + x, 2 * u * v + y)
Also, may I suggest that you use Data.Complex for your application? This makes the constraints on a a bit stricter (you need RealFloat a, because of Num.signum), but in my opinion, it makes your code much easier to read:
import Data.Complex
import Data.List (iterate)
{- ... -}
o :: Num (Complex a) => Complex a -> [Complex a]
o c = tail (iterate p iv)
where
iv = 0 -- or "0 :+ 0", if you want to be explicit
p z = z^2 + c
You want:
To construct a list [(u, v)] with the head of this list equal (0, 0)
And then map this list with the function \(u, v) -> (u^2 - v^2 + x, 2 * u * v + y), appending results of this function to the list.
We can write this function as described:
func :: (Num t) => (t, t) -> [(t, t)]
func (x, y) = (0, 0) : map functionP (func (x, y))
where functionP (u, v) = (u^2 - v^2 + x, 2 * u * v + y)
GHCi > take 5 $ func (1, 2)
> [(0,0),(1,2),(-2,6),(-31,-22),(478,1366)]