How can I write a nat in the form of term? - coq

All
I am trying to complete the last execrise in the StlcProp of Software Foundations Vol2.
But I got stuck at defining step, in the rule ST_SuccNat.
Inductive step : tm -> tm -> Prop :=
| ST_AppAbs : forall x T2 t1 v2,
value v2 ->
<{(\x:T2, t1) v2}> --> <{ [x:=v2]t1 }>
| ST_App1 : forall t1 t1' t2,
t1 --> t1' ->
<{t1 t2}> --> <{t1' t2}>
| ST_App2 : forall v1 t2 t2',
value v1 ->
t2 --> t2' ->
<{v1 t2}> --> <{v1 t2'}>
| ST_SuccNat: forall n:nat,
<{succ n}> --> <{ S n }> (* <----- stuck here *)
Coq complains as below
In environment
step : tm -> tm -> Prop
n : nat
The term "S" has type "nat -> nat" while it is expected to have type "tm".
How can I tell Coq the S n in the form of "tm" ?
Thanks

I think you can do
<{succ n}> --> S n
(* which desugars to succ (tm_const n) --> tm_const (S n) *)
The <{ }> brackets change the interpretation of application. Here you want the regular function application, so don't use the brackets.

Related

ssreflect inversion, I need two equations instead of one

I have next definitions (code can be compiled):
From mathcomp Require Import all_ssreflect.
Set Implicit Arguments.
Set Asymmetric Patterns.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Inductive val : Set := VConst of nat | VPair of val & val.
Inductive type : Set := TNat | TPair of type & type.
Inductive tjudgments_val : val -> type -> Prop :=
| TJV_nat n :
tjudgments_val (VConst n) TNat
| TJV_pair v1 t1 v2 t2 :
tjudgments_val v1 t1 ->
tjudgments_val v2 t2 ->
tjudgments_val (VPair v1 v2) (TPair t1 t2).
And I would like to prove the following lemma:
Lemma tjexp_pair v1 t1 v2 t2 (H : tjudgments_val (VPair v1 v2) (TPair t1 t2)) :
tjudgments_val v1 t1 /\ tjudgments_val v2 t2.
Proof.
case E: _ _ / H => // [v1' t1' v2' t2' jv1 jv2].
(* case E: _ / H => // [v1' t1' v2' t2' jv1 jv2]. *)
The case E: _ _ / H => // [v1' t1' v2' t2' jv1 jv2]. leaves me with E : VPair v1 v2 = VPair v1' v2'.
The case E: _ / H => // [v1' t1' v2' t2TPair t1 t2 = TPair t1' t2'' jv1 jv2]. leaves me with E : TPair t1 t2 = TPair t1' t2'.
But it looks to me like I need both of them together. How to?
There is a way of using inversion's power with ssreflect tactics.
Derive Inversion tjudgments_val_inv with (forall v t, tjudgments_val v t).
You can use it with elim/tjudgments_val_inv: H.
The proof is straightforward after this.
In such a case, you can use the very handy inversion tactic an enhancement of the case tactic, which automatically does the kind of work of indices you are manually trying to do. Here inversion H is almost enough to finish the proof.

Using functions in definitions

I'm modeling a program in which users can choose from different operators and functions for writing queries (i.e. formulas) for the system. For showing these operators, here I defined add and mul functions and used nat datatype, instead of my program's functions and datatypes. How should I define formula that enables me to use it in definition compute_formula. I'm a bit stuck at solving this issue. Thank you.
Fixpoint add n m :=
match n with
| 0 => m
| S p => S (p + m)
end
where "n + m" := (add n m) : nat_scope.
Fixpoint mul n m :=
match n with
| 0 => 0
| S p => m + p * m
end
where "n * m" := (mul n m) : nat_scope.
Definition formula : Set :=
nat-> nat -> ?operators_add_mull ->formula.
Definition compute_formula (f: formula) : nat :=
match f with
|firstnumber,secondnumber, ?operators_add_mull =>
?operators_add_mull firstnumber secondnumber
end.
First, your syntax for defining a data type is not quite right: you need to use the Inductive keyword:
Inductive formula : Set :=
| Formula : nat -> nat -> ?operators_add_mul -> formula.
It remains to figure out what the arguments to the Formula constructor should be. The Coq function type -> is a type like any other, and we can use it as the third argument:
Inductive formula : Set :=
| Formula : nat -> nat -> (nat -> nat -> nat) -> formula.
After defining this data type, you can write an expression like Formula 3 5 add, which denotes the addition of 3 and 5. To inspect the formula data type, you need to write match using the Formula constructor:
Definition compute_formula (f : formula) : nat :=
match f with
| Formula n m f => f n m
end.

Coinduction on Coq, type mismatch

I've been trying out coinductive types and decided to define coinductive versions of the natural numbers and the vectors (lists with their size in the type). I defined them and the infinite number as so:
CoInductive conat : Set :=
| cozero : conat
| cosuc : conat -> conat.
CoInductive covec (A : Set) : conat -> Set :=
| conil : covec A cozero
| cocons : forall (n : conat), A -> covec A n -> covec A (cosuc n).
CoFixpoint infnum : conat := cosuc infnum.
It all worked except for the definition I gave for an infinite covector
CoFixpoint ones : covec nat infnum := cocons 1 ones.
which gave the following type mismatch
Error:
In environment
ones : covec nat infnum
The term "cocons 1 ones" has type "covec nat (cosuc infnum)" while it is expected to have type
"covec nat infnum".
I thought the compiler would accept this definition since, by definition, infnum = cosuc infnum. How can I make the compiler understand these expressions are the same?
The standard way to solve this issue is described in Adam Chlipala's CPDT (see the chapter on Coinduction).
Definition frob (c : conat) :=
match c with
| cozero => cozero
| cosuc c' => cosuc c'
end.
Lemma frob_eq (c : conat) : c = frob c.
Proof. now destruct c. Qed.
You can use the above definitions like so:
CoFixpoint ones : covec nat infnum.
Proof. rewrite frob_eq; exact (cocons 1 ones). Defined.
or, perhaps, in a bit more readable way:
Require Import Coq.Program.Tactics.
Program CoFixpoint ones : covec nat infnum := cocons 1 ones.
Next Obligation. now rewrite frob_eq. Qed.

Confused about pattern matching in Record constructions in Coq

I've been using Coq for a very short time and I still bump into walls with some things. I've defined a set with a Record construction. Now I need to do some pattern matching to use it, but I'm having issues properly using it. First, these are my elements.
Inductive element : Set :=
| empty : element
.
.
.
| fun_m : element -> element -> element
| n_fun : nat -> element -> element
.
I pick the elements with certain characteristic to make a subset of them the next way:
Inductive esp_char : elements -> Prop :=
| esp1 : esp_char empty
| esp2 : forall (n : nat )(E : element), esp_char E -> esp_char (n_fun n E).
Record especial : Set := mk_esp{ E : element ; C : (esp_char E)}.
Now, I need to use definition and fix point on the 'especial' elements, just the two that I picked. I have read the documentation on Record and what I get is that I'd need to do something like this:
Fixpoint Size (E : especial): nat :=
match E with
|{|E := empty |} => 0
|{|E := n_fun n E0|} => (Size E0) + 1
end.
Of course this tells me that I'm missing everything on the inductive part of elements so I add {|E := _ |}=> 0, or anything, just to make the induction full. Even doing this, I then find this problem:
|{|E := n_fun n E0|} => (Size E0) + 1
Error:
In environment
Size : especial -> nat
E : especial
f : element
i : esp_char f
n : nat
E0 : element
The term "E0" has type "element" while it is expected to have type "especial".
What I have been unable to do is fix that last thing, I have a lemma proving that if n_fun n E0 is 'especial' then E0 is especial, but I can't build it as so inside the Fixpoint. I also defined the size for "all elements" and then just picked the "especial" ones in a definition, but I want to be able to do direct pattern matching directly on the set "especial". Thank you for your input.
EDIT: Forgot to mention that I also have a coercion to always send especial to elements.
EDIT: This is the approach I had before posting:
Fixpoint ElementSize (E : element): nat :=
match E with
| n_fun n E0 => (ElementSize E0) + 1
| _ => 0
end.
Definition Size (E : especial) := ElementSize E.
I'd have tried to do:
Lemma mk_especial_proof n E : esp_char (n_fun n E) -> esp_char E.
Proof. now intros U; inversion U. Qed.
Fixpoint Size (E : especial): nat :=
match E with
|{|E := empty |} => 0
|{|E := n_fun n E0; C := P |} => (Size (mk_esp E0 (mk_especial_proof _ _ P))) + 1
|{|E := fun_m E1 E2 |} => 0
end.
However this will fail the termination check. I'm not familiar with how to overcome this problem with records. I'd definitively follow the approach I mentioned in the comments (using a fixpoint over the base datatype).
EDIT: Added single fixpoint solution.
Fixpoint size_e e :=
match e with
| empty => 0
| fun_m e1 e2 => 0
| n_fun _ e => 1 + size_e e
end.
Definition size_esp e := size_e (E e).
I reduced your example to this, but you can easily go back to your definition. We have a set, and a subset defined by an inductive predicate. Often one uses sigma types for this, with the notation {b | Small b}, but it is actually the same as the Record definition used in your example, so never mind :-).
Inductive Big : Set := (* a big set *)
| A
| B (b0 b1:Big)
| C (b: Big).
Inductive Small : Big -> Prop := (* a subset *)
| A' : Small A
| C' (b:Big) : Small b -> Small (C b).
Record small := mk_small { b:Big ; P:Small b }.
Here is a solution.
Lemma Small_lemma: forall b, Small (C b) -> Small b.
Proof. intros b H; now inversion H. Qed.
Fixpoint size (b : Big) : Small b -> nat :=
match b with
| A => fun _ => 0
| B _ _ => fun _ => 0
| C b' => fun H => 1 + size b' (Small_lemma _ H)
end.
Definition Size (s:small) : nat :=
let (b,H) := s in size b H.
To be able to use the hypothesis H in the match-branches, it is sent into the branch as a function argument. Otherwise the destruction of b is not performed on the H term, and Coq can't prove that we do a structural recursion on H.

Using sets as hyphotesis and goal in COQ

How exactly could a proof like the following be completed?
1 subgoals
IHt1 : {t' : some_type | something_using t'}
IHt2 : {t' : some_type | something_else_using t'}
______________________________________(1/1)
{t' : some_type | another_thing_involving t'}
I do understand that the {x|P x} notation is a shorthand for the sig definition but I really cannot understand how to use it.
{x : D | P x} is intuitively speaking the subset of the domain D containing the elements that satisfy the predicate P. As a proposition, it is true if that subset is non-empty, i.e. if there is a witness x0 in D such that P x0 is true.
An object of type {x : D | P x} is a pair containing an element x0 : D and a proof of P x0. This is visible when you look at the definition of {x : D | P x}, which is syntactic sugar for sig (fun x:D => P x)
Inductive sig (D:Type) (P:D -> Prop) : Type :=
exist : forall x:D, P x -> sig P.
The type of the constructor is a dependent pair type; the first element of the pair has the type D and the second element has the type P x in which x is the first element.
To make use of a hypothesis of the form {x : D | P x}, the most basic way is to use the destruct tactic to break it down into its two components: a witness x0 : D and a proof H : P x0.
destruct IHt1.
1 subgoals
t' : some_type
H : something_using t'
IHt2 : {t'0 : some_type | something_else_using t'0}
______________________________________(1/1)
{t'0 : some_type | another_thing_involving t'0}
To prove a goal of the form {x : D | P x}, the most basic is to use the exist tactic to introduce the intended witness. This leaves one subgoal which is to prove that the witness has the desired property.
exists u.
⋮
______________________________________(1/1)
another_thing_involving u