English 中文(简体)
Pattern matching not specialising types
原标题:

I m playing around in Coq, trying to create a sorted list. I just wanted a function that takes a list [1,2,3,2,4] and would return something like Sorted [1,2,3,4] - i.e. taking out the bad parts, but not actually sorting the entire list.

I thought I would start by defining a function lesseq of type (m n : nat) -> option (m <= n), and then I could pattern match on that pretty easily. Maybe that s is a bad idea.

The crux of the issue I m having right now is that (snippet, whole function at bottom)

Fixpoint lesseq (m n : nat) : option (m <= n) :=
    match m with
        | 0 => match n with
            | 0 => Some (le_n 0)
            ...

is not typechecking; it says that it s expecting an option (m <= n), but that Some (le_n 0) has type option (0 <= 0). I don t understand, because obviously both m and n are zero in that context, but I ve no idea how to tell Coq that.

The entire function is:

Fixpoint lesseq (m n : nat) : option (m <= n) :=
    match m with
    | 0 => match n with
        | 0 => Some (le_n 0)
        | S n_  => None
        end
    | S m_  => match n with
        | 0 => None
        | S _   => match lesseq m_ n with
                | Some x=> le_S m n x
                | None  => None
                end
            end
    end.

Perhaps I m getting ahead of myself and just need to keep reading before I tackle this.

最佳回答

You probably want to define the following function (even if you annotate it properly you [le_S m n x] does not have the type you want) :

     Fixpoint lesseq (m n : nat) : option (m <= n) :=
     match n with
     | 0 =>
         match m with
         | 0 => Some (le_n 0)
         | S m0 => None
         end
     | S p =>
         match lesseq m p with
         | Some l => Some (le_S m p l)
         | None => None
         end
     end.

But as you ve noticed, the typechecker is not clever enough to guess the new context when you destruct a variable appearing in the type of the result. You have to annotate the match in the following way :

     Fixpoint lesseq (m n : nat) : option (m <= n) :=
     match n return (option (m <= n)) with
     | 0 =>
         match m return (option (m <= 0)) with
         | 0 => Some (le_n 0)
         | S m0 => None
         end
     | S p =>
         match lesseq m p with
         | Some l => Some (le_S m p l)
         | None => None
         end
     end.

See the reference manual if you really want to understand how pattern matching works with dependent types. If you don t feel brave enough for that, you d rather use tactics mechanisms to build your proof (the "refine" tactic is a great tool for that).

     Definition lesseq m n : option (m <= n).
     refine (fix lesseq (m : nat) (n : nat) {struct n} := _).

     destruct n.
     destruct m.
     apply Some; apply le_n.
     apply None.

     destruct (lesseq m n).
     apply Some.
     apply le_S.
     assumption.
     apply None.
     Defined.

By the way, I don t think your function will be really helpfull (even if it is a good idea), because you will need to prove the following lemma : Lemma lesseq_complete: forall m n, lesseq m n <> None -> m > n.

This is why people use Coq.Arith.Compare_dec. Have fun.

问题回答

Do you want to write this function as an exercise or only to accomplish your bigger goal? In the latter case you should take a look at the standard library, which is full of decision functions that would do the job here, Coq.Arith.Compare_dec; see for instance le_gt_dec.

Also note that the function you propose would only give you information whether m <= n. For pattern matching the sum type { ... } + { ... } is much more useful, giving you two possible cases to deal with.





相关问题
How do I reason about conditionals in Coq?

I m working through the ListSet module from the Coq standard library. I m unsure how to reason about conditionals in a proof. For instance, I am having trouble with the following proof. Definitions ...

Z3: Extracting existential model-values

I m playing around with Z3 s QBVF solver, and wondering if it s possible to extract values from an existential assertion. To wit, let s say I have the following: (assert (exists ((x (_ BitVec 16))) (...

Tautology Checker for GNU Prolog [closed]

I am looking for open-source implementations of tautology checkers written in GNU Prolog (implementation for SWI-Prolog is acceptable as well, but GNU Prolog is preferred). I d like to feed program ...

Has anyone tried proving Z3 with Z3 itself?

Has anyone tried proving Z3 with Z3 itself? Is it even possible, to prove that Z3 is correct, using Z3? More theoretical, is it possible to prove that tool X is correct, using X itself?

How to proceed with this Coq Proof?

I m having a problem with my Coq proof and was hoping for some help and guidance. I have part of my definition below: Inductive Architecture : Set := | Create_Architecture (Arch_Name: string)(...

Searching through a list recursively in Coq

Im trying to search for an object in a list, and then perhaps return true if it is found; false otherwise. However, what I have tried to come up with is incorrect. I would really appreciate some ...

Pattern matching not specialising types

I m playing around in Coq, trying to create a sorted list. I just wanted a function that takes a list [1,2,3,2,4] and would return something like Sorted [1,2,3,4] - i.e. taking out the bad parts, but ...

Showing (head . init ) = head in Agda

I m trying to prove a simple lemma in Agda, which I think is true. If a vector has more than two elements, taking its head following taking the init is the same as taking its head immediately. I ...

热门标签