Inductive proposition for sublists in Coq - coq

I am struggling with coming up with a notion of sublist of a list, which is created by deleting elements in the list (so that the order is preserved). I need to come up with an inductive proposition that decides if l1 is a sublist of l2.
So far:
I know the empty list is a sublist of all lists.
All lists are sublists of themselves.
If it is known that l1 is a sublist of l2, then lists resulting from appending the same list to both l1 and l2 at the head or tail would result in the former being a sublist of the latter
Now is the hard part. How to provide evidence that a list like ["x";"y"] is a sublist of ["a";"x";"z";"y"]?
The syntax is something like
Inductive Sublist {X : Type} : list X -> list X -> Prop := ..
Can someone please help me with it?

How would you do informally already? Using just your three rules. If you can't manage it means that you have perhaps a too complicated / incomplete definition.
I think instead of trying to think of all those complicated examples you could focus on your example(s) while keeping in mind how lists are constructed.
Why is [ x ; y ] a sublist of [ a ; x ; y ; z ]? Because (without the head of the second list) [ x ; y ] is a sublist of [ x ; y ; z ], and that's because [ y ] is a sublist of [ y ; z ], which is because [] is a sublist of [ z ] which always holds.
Do you see a pattern?

Related

Add ltac expression as hint to autorewrite?

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

How do I use value of variable in Maple

How do I get Maple to give the value of a variable in the RHS of an expression, rather than treat it as a variable in an expression. In the following code I want a list of three functions of x which are quadratics with different offsets, but it's not what I get:
ix := [-1,0,1]:
b := []:
for a in ix
do
b := [op(b),x->(x-a)^2];
end do;
and the output is
while I would like it to be (for the last line)
b := [ x -> (x+1)^2, x -> x^2, x -> (x-1)^2 ]
Your problem is that you are trying to use values for a in the construction of the body of a procedure, and not the "RHS of an expression" as you stated.
Try not to use the term "function" in this context, as it just muddles the distinction between expression and procedure.
Here is a way to get the values from ix as replacements for a in a generated list of procedures with (x-a)^2 in the body.
restart;
ix := [-1,0,1]:
b := []:
for a in ix do
b := [op(b), unapply((x-a)^2,x)];
end do:
b;
[x -> (x+1)^2, x -> x^2, x -> (x-1)^2]
It is inefficient to construct lists in this way, by repeatedly concatenating them. Since that practice scales badly in performance you really ought to drop it as a practice.
You can construct the whole list with one call to seq.
Flist := [ seq( unapply((x-a)^2,x), a in ix ) ]:
Flist;
[x -> (x+1)^2, x -> x^2, x -> (x-1)^2]
Here, Flist is a list of procedures, each of which can be evaluated at a value by calling it with an argument.
Flist[1];
x -> (x+1)^2
Flist[3](3.4);
5.76
#plot(Flist, -2..2);
Note: Procedures which display with the arrow notation x -> ... are called operators.
For fun, here are equivalents, using expressions,
Elist := [ seq( (x-a)^2, a in ix ) ]:
Elist;
[ 2 2 2]
[(x + 1) , x , (x - 1) ]
Elist[1];
2
(x + 1)
eval(Elist[3], x=3.4);
5.76
#plot(Elist, x=-2..2);
There are other ways to generate the procedures, with values of a in the body being specified programmatically. The unapply command is not the only possible mechanism, although it is the easiest for your example.
Another way is to substitute, for example,
generic := x -> (x-_dummy)^2:
Hlist := [ seq( subs(_dummy=a, eval(generic)), a in ix ) ]:
Hlist;
[x -> (x+1)^2, x -> x^2, x -> (x-1)^2]

how to figure out what "=" means in different types in coq

Given a type (like List) in Coq, how do I figure out what the equality symbol "=" mean in that type? What commands should I type to figure out the definition?
The equality symbol is just special infix syntax for the eq predicate. Perhaps surprisingly, it is defined the same way for every type, and we can even ask Coq to print it for us:
Print eq.
(* Answer: *)
Inductive eq (A : Type) (x : A) : Prop :=
| eq_refl : eq x x.
This definition is so minimal that it might be hard to understand what is going on. Roughly speaking, it says that the most basic way to show that two expressions are equal is by reflexivity -- that is, when they are exactly the same. For instance, we can use eq_refl to prove that 5 = 5 or [4] = [4]:
Check eq_refl : 5 = 5.
Check eq_refl : [4] = [4].
There is more to this definition than meets the eye. First, Coq considers any two expressions that are equalivalent up to simplification to be equal. In these cases, we can use eq_refl to show that they are equal as well. For instance:
Check eq_refl : 2 + 2 = 4.
This works because Coq knows the definition of addition on the natural numbers and is able to mechanically simplify the expression 2 + 2 until it arrives at 4.
Furthermore, the above definition tells us how to use an equality to prove other facts. Because of the way inductive types work in Coq, we can show the following result:
eq_elim :
forall (A : Type) (x y : A),
x = y ->
forall (P : A -> Prop), P x -> P y
Paraphrasing, when two things are equal, any fact that holds of the first one also holds of the second one. This principle is roughly what Coq uses under the hood when you invoke the rewrite tactic.
Finally, equality interacts with other types in interesting ways. You asked what the definition of equality for list was. We can show that the following lemmas are valid:
forall A (x1 x2 : A) (l1 l2 : list A),
x1 :: l1 = x2 :: l2 -> x1 = x2 /\ l1 = l2
forall A (x : A) (l : list A),
x :: l <> nil.
In words:
if two nonempty lists are equal, then their heads and tails are equal;
a nonempty list is different from nil.
More generally, if T is an inductive type, we can show that:
if two expressions starting with the same constructor are equal, then their arguments are equal (that is, constructors are injective); and
two expressions starting with different constructors are always different (that is, different constructors are disjoint).
These facts are not, strictly speaking, part of the definition of equality, but rather consequences of the way inductive types work in Coq. Unfortunately, it doesn't work as well for other kinds of types in Coq; in particular, the notion of equality for functions in Coq is not very useful, unless you are willing to add extra axioms into the theory.

Counting number of different elements in a list in Coq

I'm trying to write a function that takes a list of natural numbers and returns as output the amount of different elements in it. For example, if I have the list [1,2,2,4,1], my function DifElem should output "3". I've tried many things, the closest I've gotten is this:
Fixpoint DifElem (l : list nat) : nat :=
match l with
| [] => 0
| m::tm =>
let n := listWidth tm in
if (~ In m tm) then S n else n
end.
My logic is this: if m is not in the tail of the list then add one to the counter. If it is, do not add to the counter, so I'll only be counting once: when it's the last time it appears. I get the error:
Error: The term "~ In m tm" has type "Prop"
which is not a (co-)inductive type.
In is part of Coq's list standard library Coq.Lists.List. It is defined there as:
Fixpoint In (a:A) (l:list A) : Prop :=
match l with
| [] => False
| b :: m => b = a \/ In a m
end.
I think I don't understand well enough how to use If then statements in definitions, Coq's documentation was not helpful enough.
I also tried this definition with nodup from the same library:
Definition Width (A : list nat ) := length (nodup ( A ) ).
In this case what I get as error is:
The term "A" has type "list nat" while it is expected to have
type "forall x y : ?A0, {x = y} + {x <> y}".
And I'm quiet confused as to what's going on here. I'd appreciate your help to solve this issue.
You seem to be confusing propositions (Prop) and booleans (bool). I'll try to explain in simple terms: a proposition is something you prove (according to Martin-Lof's interpretation it is a set of proofs), and a boolean is a datatype which can hold only 2 values (true / false). Booleans can be useful in computations, when there are only two possible outcomes and no addition information is not needed. You can find more on this topic in this answer by #Ptival or a thorough section on this in the Software Foundations book by B.C. Pierce et al. (see Propositions and Booleans section).
Actually, nodup is the way to go here, but Coq wants you to provide a way of deciding on equality of the elements of the input list. If you take a look at the definition of nodup:
Hypothesis decA: forall x y : A, {x = y} + {x <> y}.
Fixpoint nodup (l : list A) : list A :=
match l with
| [] => []
| x::xs => if in_dec decA x xs then nodup xs else x::(nodup xs)
end.
you'll notice a hypothesis decA, which becomes an additional argument to the nodup function, so you need to pass eq_nat_dec (decidable equality fot nats), for example, like this: nodup eq_nat_dec l.
So, here is a possible solution:
Require Import Coq.Arith.Arith.
Require Import Coq.Lists.List.
Import ListNotations.
Definition count_uniques (l : list nat) : nat :=
length (nodup eq_nat_dec l).
Eval compute in count_uniques [1; 2; 2; 4; 1].
(* = 3 : nat *)
Note: The nodup function works since Coq v8.5.
In addition to Anton's solution using the standard library I'd like to remark that mathcomp provides specially good support for this use case along with a quite complete theory on count and uniq. Your function becomes:
From mathcomp Require Import ssreflect ssrfun ssrbool eqtype ssrnat seq.
Definition count_uniques (T : eqType) (s : seq T) := size (undup s).
In fact, I think the count_uniques name is redundant, I'd prefer to directly use size (undup s) where needed.
Using sets:
Require Import MSets.
Require List. Import ListNotations.
Module NatSet := Make Nat_as_OT.
Definition no_dup l := List.fold_left (fun s x => NatSet.add x s) l NatSet.empty.
Definition count_uniques l := NatSet.cardinal (no_dup l).
Eval compute in count_uniques [1; 2; 2; 4; 1].

Coq notation for multi type list

Here is a contrived multi type list:
Inductive Apple : Set :=.
Inductive Pear : Set :=.
Inductive FruitList : Set :=
| Empty
| Cons_apple (a : Apple) (p : FruitList)
| Cons_pear (p : Pear) (p: FruitList).
Variable a : Apple.
Variable p : Pear.
Definition a_fruitList := Cons_apple a (Cons_pear p Empty).
Is there a way to define a list notation for this so that, for example, a_fruitList could have been defined by [p,a] instead?
The problem is that your list has two cons constructors, whereas the usual notation mechanism for recursive notations requires you to use always the same constructors. Coercions can help you overcome part of this problem:
Section ApplesAndPears.
Variable Apple Pear : Set.
Inductive FruitList : Set :=
| Nil
| ConsApple (a : Apple) (l : FruitList)
| ConsPear (p : Pear) (l : FruitList).
Inductive Fruit : Set :=
| IsApple (a : Apple)
| IsPear (p : Pear).
Coercion IsApple : Apple >-> Fruit.
Coercion IsPear : Pear >-> Fruit.
Definition ConsFruit (f : Fruit) (l : FruitList) : FruitList :=
match f with
| IsApple a => ConsApple a l
| IsPear p => ConsPear p l
end.
Notation "[ ]" := (Nil) (at level 0).
Notation "[ x ; .. ; y ]" := (ConsFruit x .. (ConsFruit y Nil) ..) (at level 0).
Variable a : Apple.
Variable p : Pear.
Definition a_fruitList := [ a ; p ].
End ApplesAndPears.
(By the way, I'm assuming that you really meant to write [ a ; p ], and not [ p ; a ]. If you did mean to write [ p ; a ], then you just have to use a SnocFruit function instead, that adds the element to the end of the list. However, this would make the problems explained later even worse.)
Now, we've defined a new function to replace the constructors, and can use that function instead, by declaring the constructors of Fruit to be coercions.
This solution is not entirely satisfactory, of course, because the term your notation produces makes reference to ConsFruit, while ideally it would be nice to have something that picks ConsApple or ConsFruit depending on the argument you give. I suspect there isn't a way of doing this with the notation mechanism, but I could be wrong.
This is one of the reasons why I would recommend you to use just the list type and declare another type such as Fruit to hold Apple and Pear instead of using two cons constructors, unless you have a very good reason not to.
As mentioned by Arthur Azevedo De Amorim, the issue is that the Notation mechanism of Coq does not take the types of the sub-expressions into account to discriminate between Cons_apple and Cons_pear. However, you can use Type Classes to do that:
Class Cons_fruit(A:Set) := {
CONS: A -> FruitList -> FruitList }.
Instance Cons_fruit_apple: Cons_fruit Apple:= { CONS := Cons_apple }.
Instance Cons_fruit_pear: Cons_fruit Pear := { CONS := Cons_pear }.
Notation " [ x ; .. ; y ] " := (CONS x .. (CONS y Empty) .. ).
Definition test := [a; p; p; a ].
We define here a type class Cons_fruit containing a single function, and two instances, one for consing apples and one for consing pears. We can then use the templated CONS function in the notation, and Coq will select the appropriate instance when needed.
Note that this may result in less understandable error messages. For instance, with
Definition bad:= [ 0; p ].
You will get
Error: Cannot infer the implicit parameter Cons_fruit of CONS.
Could not find an instance for "Cons_fruit nat".
Here is an extract from Coq's documentation about lists
Notation " [ ] " := nil : list_scope.
Notation " [ x ] " := (cons x nil) : list_scope.
Notation " [ x ; .. ; y ] " := (cons x .. (cons y nil) ..) : list_scope.
I would stick to using ; and not , since the latter is often use in Coq's syntax, it might be tricky to get the notation priority correctly.
Best,
V.