Add ltac expression as hint to autorewrite? - coq

I am trying to rewrite an environment using autorewrite. For simplicity we can assume it is a list (but in reality the type is more complex, has multiple cons constructors, and rewrite rules use equivalence rather than equality).
The normal form I want to get to is a concatenation of variables or singleton lists, i.e. x1 :: x2 :: xs ++ y :: ys to [x1] ++ [x2] ++ xs ++ [y] ++ ys. So far I had success rewriting other stuff by defining hints for autorewrite. However, the hint forall x xs, xs :: x = xs ++ [x] does not work, since [x] = x : [] which then can be rewritten to [x] ++ [] which gives an endless loop.
I don't have too much experience with writing custom Ltac expressions, but it seems like I would be able to define something like:
Ltac norm_cons :=
match goal with
| H: ?X : [] => idtac
| H: ?X : ?XS => (* actual rewrite *)
end.
This way we catch the [] in the first pattern and skip rewriting, and otherwise perform the rewrite. Maybe this needs a falltrough case, but this is not the point: how do I give (something like) this as a hint to autorewrite? I have tried to define the above as a separate tactic (where maybe I can define normalize as (norm_cons; autorewrite with blablabla).) but it then complains about none of the branches in the match matching to my goal. Does this do a recursive search? Or do I have to add this myself (i.e. matching ?XS ++ ?YS and recursively rewriting the lhs and rhs?)

It seems like you only want to rewrite lists with at least two elements. Perhaps you could rewrite with
forall x y xs, x :: y :: xs = [x] ++ y::xs

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.

Merge duplicate cases in match Coq

I have come by this problem many times: I have a proof state in Coq that includes matches on both sides of an equality that are the same.
Is there a standard way to rewrite multiple matches into one?
Eg.
match expression_evaling_to_Z with
Zarith.Z0 => something
Zartih.Pos _ => something_else
Zarith.Neg _ => something_else
end = yet_another_thing.
And if I destruct on expresion_evaling_to_Z I get two identical goals. I would like to find a way to get only one of the goals.
A standard solution is to define "a view" of your datatype using a type family that will introduce the proper conditions and cases when destructed. For your particular case, you could do:
Require Import Coq.ZArith.ZArith.
Inductive zero_view_spec : Z -> Type :=
| Z_zero : zero_view_spec Z0
| Z_zeroN : forall z, z <> Z0 -> zero_view_spec z.
Lemma zero_viewP z : zero_view_spec z.
Proof. now destruct z; [constructor|constructor 2|constructor 2]. Qed.
Lemma U z : match z with
Z0 => 0
| Zpos _ | Zneg _ => 1
end = 0.
Proof.
destruct (zero_viewP z).
Abort.
This is a common idiom in some libraries like math-comp, which provides special support for instantiating the z argument of the type family.
You can write the match expression more succinctly:
match expression_evaling_to_Z with
| Z0 => something
| Zpos _ | Zneg _ => something_else
end = yet_another_thing.
But that will give you 3 subgoals when using destruct.
In this particular case we may use the fact that you actually need to distinguish the zero and non-zero cases, and it looks like a job for the Z.abs_nat : Z -> nat function.
Require Import Coq.ZArith.BinIntDef.
match Z.abs_nat (expression_evaling_to_Z) with
| O => something
| S _ => something_else
end = yet_another_thing.
This will get you only two subcases, but you need to destruct on Z.abs_nat (expression_evaling_to_Z) or introduce a new variable. If you choose the 1st variant, then you'll probably need destruct (...) eqn:Heq. to put the equation into context.
Basically this approach is about finding a new datatype (or defining one) and a suitable function to map from the old type to the new one.
If you don't mind typing you can use replace to replace the RHS with the LHS of your goal, which makes it trivial to solve, and then you just have to prove once that the rewrite is indeed ok.
Open Scope Z.
Lemma L a b :
match a + b with
Z0 => a + b
| Zpos _ => b + a
| Zneg _ => b + a
end = a + b.
replace (b+a) with (a+b). (* 1. replace the RHS with something trivially true *)
destruct (a+b); auto. (* 2. solve the branches in one fell swoop *)
apply Z.add_comm. (* 3. solve only once what is required for the two brances *)
Qed.
Perhaps you can use some Ltac-fu or other lemma to not have to type in the RHS manually too.

How do I check for convertibility in a tactic producing terms?

Suppose I have the following tactic to check if a term is the literal zero:
Ltac isZero x :=
match x with
| O => constr:true
| _ => constr:false
end.
Goal Set.
let isz := isZero O in pose isz.
(* adds true to the context *)
Now imagine that I want the tactic to accept a bit more; maybe any term that is convertible with zero. If this was a tactic acting on the goal, I would do
Ltac isZero x :=
match x with
| ?v => unify v 0; constr:true
| _ => constr:false
end.
but this fails for a tactic producing terms:
Error: Value is a term. Expected a tactic.
How can I check for convertibility in a tactic producing terms? In this specific example reducing x or computing it (let xx := eval compute in x) may work, but in more complex example the cost of computing could be prohibitive, especially as I would need to reduce the two terms of the comparison.
PS: For reference, the unsimplified issue is that I'm trying to efficiently lookup a key probably matching a value in an FMap built by sequences of calls to add, and the tactic looks like
Ltac find_key value :=
match fmap with
| add ?k value _ => constr:(Some k)
| add _ _ ?m => find_key value m
| _ => constr:None
end
With this implementation, if instead of value the map contains a term convertible to value but not syntactically equal to it, the tactic will incorrectly return None.
You can try to construct a term that triggers the conversion check; for instance:
Goal 2 + 2 = 4.
match goal with
| |- ?a = ?b =>
let e := constr:(eq_refl a : a = b) in
idtac "equal"
| |- _ => idtac "not equal"
end.
Normally, this prints "equal". However, if you replace 4 by, say, 3 in the goal above, the inner branch fails, printing "not equal".

Limitations of Fixpoint in Coq?

I am fooling around with Coq. Specifically, I am trying to implement mergesort and then prove that it works.
My attempt at an implementation was:
Fixpoint sort ls :=
match ls with
| nil => nil
| cons x nil => cons x nil
| xs =>
let (left, right) := split xs nil nil
in merge (sort left) (sort right)
end.
The errors that I get as a result of this are:
Error:
Recursive definition of sort is ill-formed.
In environment
sort : list nat -> list nat
ls : list nat
x : nat
l : list nat
y : nat
l0 : list nat
left : list nat
right : list nat
Recursive call to sort has principal argument equal to "left" instead of
one of the following variables: "l" "l0".
Recursive definition is:
"fun ls : list nat =>
match ls with
| nil => nil
| x :: nil => x :: nil
| x :: _ :: _ =>
let (left, right) := split ls nil nil in merge (sort left) (sort right)
end".
My interpretation of these errors is that l and l0 are ls without its head, x, and ls without x and the element after x (which I guess it decided to call y?). It is mad that I did not recurse on one of these lists and instead recursed on a locally defined list.
Am I only allowed to recurse on things that come directly from the pattern match? If yes, this seems like a severe limitation. Are there ways around it? I am guessing that Coq can't tell that the function will terminate. Is there some way to prove to it that left and right are smaller than xs?
It turns out that the chapter of CPDT on General Recursion addresses just that particular issue:
http://adam.chlipala.net/cpdt/html/GeneralRec.html
Read the section called Well-founded recursion, it implements the merge sort using well-founded recursion to help Coq's termination checker be happy.
There may be other ways to solve that problem using either Function or Program Fixpoint, but I think reading about well-founded recursion will not hurt.