Working with options in SML, pattern matching - smlnj

I am trying to build a get element from list function in SML:
fun get_nth e =
case e of
[] => NONE
| (x::xs, n) => if n = 1
then SOME x
else SOME get_nth(xs, n-1)
This produces the following error:
hw1pm.sml:72.24-72.45 Error: operator is not a function [tycon mismatch]
operator: ('Z -> 'Y) option
in expression:
(SOME get_nth) (xs,n - 1)
hw1pm.sml:68.5-72.45 Error: types of rules do not agree [tycon mismatch]
earlier rule(s): 'Z list -> 'Y option
this rule: _ list * [- ty] -> _ option
in rule:
(:: (x,xs),n) =>
if n = 1 then SOME x else (SOME get_nth) (xs,<exp> - <exp>)
I don't think I understand options well enough, what am I doing wrong?

get_nth already produces an option, so there's no need to wrap it in another "option layer" with SOME.
Also, function application binds very tightly - as SML says, you actually have the equivalent of (SOME get_nth) (xs, n-1), which means that SOME get_nth would be a function.
(If adding SOME had been correct, it would have been SOME (get_nth(xs, n-1)).)
The second error occurs because your pattern matching is also wrong; you can't have a list ([]) in one case, and a pair in another.
With those two fixes, you get
fun get_nth e =
case e of
([], _) => NONE
| (x::xs, n) => if n = 1
then SOME x
else get_nth(xs, n-1)
but it's more common to define a function with several pattern clauses than to use case:
fun get_nth ([], _) = NONE
| get_nth (x::xs, n) = if n = 1
then SOME x
else get_nth(xs, n-1)

Related

multiplication of two binary numbers

I need to do the function that multiplicates two binary numbers represented by a list of booleans.
Here what I wrote :
Fixpoint brmul_r (x y res: list bool): list bool :=
match x,y,res with
|x,y,res-> if value x >0 then res else if (value x) mod 2 = 0 then brmul_r ((value x/2) (value y*2) (badd res y))
else brmul_r (x y*2 res)
end.
but it doesn't work.. what should I do?
Thank you in advance!
There are many problems with that code:
Syntax error: you want to use => instead of -> inside the match.
Actually, you are not taking advantage of the patter matching, so you can remove it entirely and start your definition with if ....
Then Coq complains that _ > _ has type Prop. You need to use the boolean version _ <? _ instead, and the same for the equality later: _ =? _ instead of _ = _.
In brmul_r ((value x/2) (value y*2) (badd res y)), the outer brackets are not supposed to be there; brmul_r is supposed to receive three arguments, not one argument, and similarly for brmul_r (x y*2 res)
What do you mean by value x/2? Is it value (x / 2) or (value x) / 2? The former does not type-check unless you redefined the _ / _ notation to work over lists of booleans. But the latter has type nat, and brmul_r expects something of type list bool, so it doesn't work either. A similar observation holds for value y*2.
This is not something Coq complains about yet (the problem in 5 would have to be solved first), but it will not be clear for Coq that your definition terminates, since you are using brmul_r to define brmul_r and feeding it non-structurally decreasing arguments. In fact, you even feed it increasing arguments in the final branch (I'm talking about brmul_r x y*2 res).
So what should one do? Convincing Coq that the function terminates is the real issue here, the rest is just confusion over syntax. Since this is a function on lists, it should recurse on the list structure, so it should have the following basic shape (I am assuming the context of Require Import List. Import ListNotations.):
Fixpoint brmul_r (xs ys : list bool) : list bool :=
match xs with
| [] => (* TODO *)
| hd :: tl => (* TODO *)
end.
Assuming the first element of the list is the least significant bit, it will be useful to match on it as well, so the structure becomes:
Fixpoint brmul_r (xs ys : list bool) : list bool :=
match xs with
| [] => (* TODO *)
| false :: tl => (* TODO *)
| true :: tl => (* TODO *)
end.
Now the goal is to express the product of false :: tl with ys when we already know the product of tl with ys. Translating to numbers (for intuition's sake), we want to find (2 * (value tl)) * (value ys) when we already know how to compute (value tl) * (value ys). Putting it like this, it becomes clear that we just need to duplicate the result of the latter. Going back to our list representation, we observe that duplicating corresponds to preppending false, so we can update our definition as follows:
Fixpoint brmul_r (xs ys : list bool) : list bool :=
match xs with
| [] => (* TODO *)
| false :: tl => false :: brmul_r tl ys
| true :: tl => (* TODO *)
end.
Now you can use the same reasoning to complete the function.
For the future:
Please include the necessary context. In this case it would be the modules you imported and the custom defined functions such as value.
It might be useful to follow a Coq tutorial to help with all the syntax issues and with the intuitions behind recursive and functional programming. Software Foundations is very good. There are also others.
There is now a dedicated Stack Exchange site for Proof Assistant-related questions.

How does one do an else statement in Coq's functional programming language?

I am trying to count the # of occurrences of an element v in a natlist/bag in Coq. I tried:
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => 0
| h :: tl => match h with
| v => 1 + (count v tl)
end
end.
however my proof doesn't work:
Example test_count1: count 1 [1;2;3;1;4;1] = 3.
Proof. simpl. reflexivity. Qed.
Why doesn't the first piece of code work? What is it doing when v isn't matched?
I also tried:
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => 0
| h :: tl => match h with
| v => 1 + (count v tl)
| _ => count v tl
end
end.
but that also gives an error in Coq and I can't even run it.
Functional programming is sort of new to me so I don't know how to actually express this in Coq. I really just want to say if h matches v then do a +1 and recurse else only recurse (i.e. add zero I guess).
Is there a simple way to express this in Coq's functional programming language?
The reason that I ask is because it feels to me that the match thing is very similar to an if else statement in "normal" Python programming. So either I am missing the point of functional programming or something. That is the main issue I am concerned I guess, implicitly.
(this is similar to Daniel's answer, but I had already written most of it)
Your problem is that in this code:
match h with
| v => 1 + (count v tl)
end
matching with v binds a new variable v. To test if h is equal to v, you'll have to use some decision procedure for testing equality of natural numbers.
For example, you could use Nat.eqb, which takes two natural numbers and returns a bool indicating whether they're equal.
Require Import Nat.
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => 0
| h :: tl => if (eqb h v) then (1 + count v t1) else (count v t1)
end.
Why can't we simply match on the term we want? Pattern matching always matches on constructors of the type. In this piece of code, the outer match statement matches with nil and h :: t1 (which is a notation for cons h t1 or something similar, depending on the precise definition of bag). In a match statement like
match n with
| 0 => (* something *)
| S n => (* something else *)
end.
we match on the constructors for nat: 0 and S _.
In your original code, you try to match on v, which isn't a constructor, so Coq simply binds a new variable and calls it v.
The match statement you tried to write actually just shadows the v variable with a new variable also called v which contains just a copy of h.
In order to test whether two natural numbers are equal, you can use Nat.eqb which returns a bool value which you can then match against:
Require Import Arith.
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => 0
| h :: tl => match Nat.eqb v h with
| true => 1 + (count v tl)
| false => count v tl
end
end.
As it happens, for matching of bool values with true or false, Coq also provides syntactic sugar in the form of a functional if/else construct (which is much like the ternary ?: operator from C or C++ if you're familiar with either of those):
Require Import Arith.
Fixpoint count (v:nat) (s:bag) : nat :=
match s with
| nil => 0
| h :: tl => if Nat.eqb v h then
1 + (count v tl)
else
count v tl
end.
(Actually, it happens that if works with any inductive type with exactly two constructors: then the first constructor goes to the if branch and the second constructor goes to the else branch. However, the list type has nil as its first constructor and cons as its second constructor: so even though you could technically write an if statement taking in a list to test for emptiness or nonemptiness, it would end up reversed from the way you would probably expect it to work.)
In general, however, for a generic type there won't necessarily be a way to decide whether two members of that type are equal or not, as there was Nat.eqb in the case of nat. Therefore, if you wanted to write a generalization of count which could work for more general types, you would have to take in an argument specifying the equality decision procedure.

Proof the concatenation of ordered list is an ordered list in Stainless

I have the following code for sorting arrays which I want to verify in Stainless (previously known as Leon):
import stainless.lang._
import stainless.collection._
object QuickSort {
def isSorted(list: List[BigInt]): Boolean = list match {
case Cons(x, xs # Cons(y, _)) => x <= y && isSorted(xs)
case _ => true
}
def quickSort(list: List[BigInt]): List[BigInt] = (list match {
case Nil() => Nil[BigInt]()
case Cons(x, xs) => par(x, Nil(), Nil(), xs)
}) ensuring { res => isSorted(res) }
def par(x: BigInt, l: List[BigInt], r: List[BigInt], ls: List[BigInt]): List[BigInt] = {
require(l.forall(_ <= x) && r.forall(_ >= x))
ls match {
case Nil() => quickSort(l) ++ Cons(x, quickSort(r))
case Cons(x2, xs2) => if (x2 <= x) par(x, Cons(x2, l), r, xs2) else par(x, l, Cons(x2, r), xs2)
}
} ensuring {res => isSorted(res)}
}
I have plenty of directions to go from here (as it doesn't succeed to verify) however it seems to me that the verification should succeed with the hints provided and I want to know why it doesn't. I explain myself:
Apparently for verifying par function I need to proof that the two cases imply the isSorted postcondition separately. Now as the second case contains a recursive call then is evident that it implies the postcondition. For the first case of par, we have that the left and right subarrays are sorted and the precondition tells me that all the elements are sorted with respect to the pivot.
This last bit should imply in my opinion that the concatenating list is sorted as well. So why does it not verify? How could instruct Stainless to verify it? Do I need to add hints on the length and size to facilitate the task to Stainless?
Edit:
def concatIsSorted(l1 : List[BigInt],l2 : List[BigInt],pivot : BigInt) : Boolean = {
require(isSorted(l1) && isSorted(l2) && l1.forall(_ <= pivot) && l2.forall(_ >= pivot))
isSorted(l1 ++ Cons(pivot,l2)) because{
l1 match{
case Nil() => isSorted(Cons(pivot,l2))
case Cons(h,Nil()) => h <= pivot && isSorted(Cons(pivot,l2))
case Cons(h,t) => h <= t.head && concatIsSorted(t,l2,pivot)
}
}
}.holds
Since this is looks like a homework question, I will try to guide you towards the solution without giving it away.
First note that the program verifies if you replace the Nil() case in par with case Nil() => Nil(). This shows that the verifier is not able to prove that the result of quickSort(l) ++ Cons(x, quickSort(r)) is sorted (but it manage to do it for Nil()!).
When --debug=verification is not sufficient to understand why the verifier is not able to prove you think it should, the way to proceed is to introduce extra functions where you can precisely state your expectations. For instance if you define:
def plusplus(l: List[BigInt], r: List[BigInt]): List[BigInt] = l ++ r
And annotate it with your what you expect the verifier to prove, that is
Assuming l and r sorted and l < r (for the appropriate definition of <)
The result of l ++ r is sorted
You will see that the verifier is not able to prove this property, meaning you need to guide the verification further with addition addition auxiliary functions, pre and postcondition.
Note that this example is taken from Dependent Types for Program Termination Verification, reading the paper might help you here.

How to match a "match" expression?

I am trying to write a rule for hypotheses, formulated with a help of match construction:
Goal forall x:nat, (match x with | 1 => 5 | _ => 10 end = 5 -> x = 1)%nat.
intros.
x : nat
H : match x with
| 0%nat => 10%nat
| 1%nat => 5%nat
| S (S _) => 10%nat
end = 5%nat
============================
x = 1%nat
How can I match such hypotheses ? The following straight forward method fails:
match goal with
|[H:match ?e with | ?a => ?x | ?b => ?y | ?c => ?z end = ?b] => idtac
end.
> Syntax error: 'end' expected after [branches] (in [match_constr]).
Pattern-matching on match statements is somewhat weird.
The first thing you should know is that, inside Coq, there's no such thing as a match on several variables or with deep matching: everything is translated in terms of simpler match statements. Thus, the term you wrote is actually syntax sugar for the following term:
match x with
| 0 => 10
| S x' =>
match x' with
| 0 => 5
| S x'' => 10
end
end
which is what Coq is hinting at when it prints your proof state. The problem is that this syntax sugar doesn't work on Ltac patterns: thus, when writing an Ltac pattern that mentions a match, you should always try to match it as if it were a one-level match.
The second problem is that you can't bind the pattern part of a match: something like
match goal with
| H : match ?x => _ | ?y => _ end = 5 |- _ => (* ... *)
end
doesn't really make sense in Ltac.
You have two choices for solving your problem, then:
Write down the match you expect with the exact list of constructors of your type on the pattern part, e.g.
match goal with
| H : match x with 0 => _ | S _ => _ end = 5 |- _ => (* ... *)
end
Use the special match (* ... *) with _ => _ end syntax, which matches any match whatsoever:
match goal with
| H : match x with _ => _ end = 5 |- _ => (* ... *)
end
Often, as in your case, one still wants to consider all branches of match, including deep ones. This idiom often comes in handy in that case:
repeat match goal with
| H : match ?x with _ => _ end = _ |- _ =>
destruct x; try solve [inversion H]
end.

How to understand function reduceLeft?

Why can (1 :: xs) be inserted?
One is cons'd onto beginning of list xs.
So List(3,2,1) becomes List(1,3,2,1) but what is significance of (1 :: xs)?
I'm having trouble understanding how this works :
def product(xs : List[Int]) = (1 :: xs) reduceLeft((x , y) => x * y)
In method signature a prefix operand (in this case (1 :: xs)) is not described? :
def reduceLeft[B >: A](f: (B, A) => B): B =
(1 :: xs) is not a prefix operand.
You are actually adding 1 before your list xs.
So product(List(3,2,1)) becomes List(1,3,2,1) reduceLeft((x,y) => x * y).
The reduceLeft function will take the 2 elements on the left and replace by the result of your function (x,y) => x * y.
In your case
List(1,3,2,1) => takes (1,3) and replaces by 1* 3 = 3 new List: List(3,2,1)
List(3,2,1) => takes (3,2) and replaces by 3 *2 = 6 new List: (6,1)
Finally takes (6,1) and get the final result 6.
As multiplying by one has no effect in the product, we add the number 1 before the List to avoid an error if the List is Empty.
Remove that and try product(List()) and you will see. If the List had at least on element (1::xs) will have no effect in your function
I believe you understand cons just fine. (1 :: xs) is simply another way to express List(1,3,2,1), on which you then invoke reduceLeft.
As for a better understanding of reduceLeft, I recently blogged this exact topic.
That's not a prefix operand--it's a method invocation on a List instance. The method reduceLeft is being called on the List (1 :: xs).
(1 :: xs) reduceLeft((x , y) => x * y)
can also be written as
(1 :: xs).reduceLeft((x , y) => x * y)
Or, even more explicitly:
val myList = (1 :: xs)
myList.reduceLeft((x , y) => x * y)