I want to define the syntax of the time delay in Coq as follows:
Inductive tcs : Type :=
| delay : nat -> tcs
| atomic : nat-> tcs.
But the natural number 0 is not allowed in the constructor delay. I also find using the subset type to define the syntax. However, the introduction of subset type leads to more complications for defining semantics. Is there an easy way to define such sytax?
In your particular case, I think the easiest thing to do is to change the interpretation of the number in the delay constructor: note that nat is isomorphic to {n : nat | n > 0} via the successor function. Therefore, all you have to do is add one to the argument of delay whenever you use it in a match expression. For instance:
Definition nat_of_tcs t :=
match t with
| delay n => S n
| atomic n => n
end.
Alternatively, you can replace nat by positive, a type defined in the standard library to represent numbers greater than 0.
In general, subset types would be the way to go. You could add a n != 0 constraint in the type of delay, or define a separate predicate on elements of tcs describing when elements are well-formed:
Definition well_formed t :=
match t with
| delay 0 => false
| _ => true
end.
Definition wftcs := { t : tcs | well_formed t = true }.
The Mathematical Components and related libraries use this pattern pervasively; check the subType class in the eqtype module, for instance. In my extensional structures library, I use the subType class to define a type of finite sets (here) by packaging a list with a proof that the list is sorted.
Related
What does the with keyword without the match do inside a inductive type in Coq?, example:
Inductive Block : Type :=
| EmptyBlk : Block
| Blk : Statement -> Block
with Statement : Type :=
| Assignment : string -> AExp -> Statement
| Seq : Statement -> Statement -> Statement
| IfElse : BExp -> Block -> Block -> Statement
| While : BExp -> Block -> Statement.
I tried checking the type of Statement and it seems its not of type block or something...So what is the point of defining it inside another inductive type rather than by itself. At least checking the type of Statement gives Set the same as for Block...
It is used to specify mutually recursive definitions. For example, consider the following two functions:
Fixpoint even (n : nat) : bool :=
match n with
| O => true
| S n => odd n
end
with odd (n : nat) : bool :=
match n with
| O => false
| S n => even n
end.
Here, you cannot define even first because it needs odd to be defined. You cannot define odd first either because it needs even. You need to be able to define both at the same time - and you do that by using the with keyword.
Your example is similar but defines inductive datatype rather than recursive function - Statement uses Block in its definition and Block uses Statement. Hence, with to define them both at the same time.
Note that this with is completely different keyword than with from the match expressions. In fact, they belong to two different languages: the former one is part of Vernacular whereas the latter is part of Gallina.
For example, if I define a function from nat to nat, it would be
Definition plusfive(a:nat): nat := a + 5.
However, I would like to define a function whose arguments are nats constructed using the "S" constructor (i.e. nonzero) is that possible to directly specify as a type? something like
Definition plusfive(a: nat.S): nat := a + 5.
(I know that for this case I could also add an argument with a proof that a is nonzero, but I am wondering if it is possible to directly name the type based on the 'S' constructor).
Functions have to be complete, so you will have to use some subtype instead of nat, or add an argument that reduces input space, for instance (H: a<>0)
Definition plusfive(a:nat) (H:a<>0) :=
match a as e return a=e -> _ with
| S _ => fun _ => a + 5
| _ => fun H0 => match (H H0) with end
end eq_refl.
However, these kinds of tricks have been discovered to be very cumbersome to work with in large developments, and often one instead uses complete functions on the base type that return dummy values for bad input values, and prove that the function is called with correct arguments separately from the function definition. See for example how division is defined in the standard library.
Require Import Nat.
Print div.
div =
fun x y : nat => match y with
| 0 => y
| S y' => fst (divmod x y' 0 y')
end
: nat -> nat -> nat
So Compute (div 1 0). gives you 0.
The nice thing is that you can use div in expressions directly, without having to interleave proofs that the denominator is non-zero. Proving that an expression is correct is then done after it has been defined, not at the same time.
I have a finite enumerated type (say T) in COQ and want to check elements for equality. This means, I need a function
bool beq_T(x:T,y:T)
The only way I managed to define such a function, is with a case by case analysis. This results in lots of match statements and looks very cumbersome. Therefore, I wonder if there is not a simpler way to achieve this.
Even simpler: Scheme Equality for ... generates two functions returning respectively a boolean and a sumbool.
The bad news is that the program that implements beq_T must necessarily consist of a large match statement on both of its arguments. The good news is that you can automatically generate/synthesize this program using Coq's tactic language. For example, given the type:
Inductive T := t0 | t1 | t2 | t3.
You can define beq_T as follows. The first two destruct tactics synthesize the code necessary to match on both x and y. The match tactic inspects the branch of the match that it is in, and depending on whether x = y, the tactic either synthesises the program that returns true or false.
Definition beq_T (x y:T) : bool.
destruct x eqn:?;
destruct y eqn:?;
match goal with
| _:x = ?T, _:y = ?T |- _ => exact true
| _ => exact false
end.
Defined.
If you want to see the synthesized program, run:
Print beq_T.
Thankfully, Coq already comes with a tactic that does almost what you want. It is called decide equality. It automatically synthesizes a program that decides whether two elements of a type T are equal. But instead of just returning a boolean value, the synthesized program returns a proof of the (in)equality of the two elements.
Definition eqDec_T (x y:T) : {x = y} + {x <> y}.
decide equality.
Defined.
With that program synthesized, it is easy to implement beq_T.
Definition beq_T' {x y:T} : bool := if eqDec_T x y then true else false.
How to define isomorphism classes in Coq?
Suppose I have a record ToyRec:
Record ToyRec {Labels : Set} := {
X:Set;
r:X->Labels
}.
And a definition of isomorphisms between two objects of type ToyRec, stating that two
objects T1 and T2 are isomorphic if there exists a bijection f:T1.(X)->T2.(X) which preserves the label of mapped elements.
Definition Isomorphic{Labels:Set} (T1 T2 : #ToyRec Labels) : Prop :=
exists f:T1.(X)->T2.(X), (forall x1 x2:T1.(X), f x1 <> f x2) /\
(forall x2:T2.(X), exists x1:T1.(X), f x1 = f x2) /\
(forall x1:T1.(X) T1.(r) x1 = T2.(r) (f x1)).
Now I would like to define a function that takes an object T1 and returns a set
containing all objects that are isomorphic to T1.
g(T1) = {T2 | Isomorphic T1 T2}
How one does such a thing in coq? I know that I might be reasoning too set theoretically
here, but what would be the right type theoretic notion of isomorphism class? Or even more basically, how one would define a set (or type) of all elemenets satisfying a given property?
It really depends on what you want to do with it. In Coq, there is a comprehension type {x : T | P x} which is the type of all elements x in type T that satisfy property P. However, it is a type, meaning that it is used to classify other terms, and not a data-structure you can compute with in the traditional sense. Thus, you can use it, for instance, to write a function on T that only works on elements that satisfy P (in which case the type of the function would be {x : T | P x} -> Y, where Y is its result type), but you can't use it to, say, write a function that computes how many elements of T satisfy P.
If you want to compute with this set, things become a bit more complicated. Let's suppose P is a decidable property so that things become a bit easier. If T is a finite type, then you can a set data-structure that has a comprehension operator (have a look at the Ssreflect library, for instance). However, this breaks when T is infinite, which is the case of your ToyRec type. As Vinz said, there's no generic way of constructively building this set as a data-structure.
Perhaps it would be easier to have a complete answer if you explained what you want to do with this type exactly.
I have a type of lists whose heads and tails must be in a certain sense "compatible":
Inductive tag := A | B. (* Just an example *)
Inductive element : tag -> tag -> Set :=
| AA : element A A
| AB : element A B
| BB : element B B. (* Also just an example *)
Inductive estack : tag -> tag -> Set :=
| ENil : forall t, estack t t
| ECons : forall r s t, element r s -> estack s t -> estack r t.
However, I do not like this code very much, for the following reasons:
It is not modular: The ad-hoc list data constructors are intrinsically coupled with the proofs that the heads and tails are compatible - the tags.
It does not favor code reuse: I am forced to redefine the usual list functions (such as list concatenation) and re-prove the usual list theorems (such as the associativity of list concatenation).
I have a different approach in mind, which consists of three steps:
Defining a single type of tagged elements (as opposed to a family of tagged types of elements):
Inductive taggedElement := Tagged : forall t1 t2, element t1 t2 -> taggedElement.
Defining the type of arbitrary (that is, either valid or invalid) lists of tagged elements:
Definition taggedElementStack := list taggedElement.
Defining a valid list of tagged elements as a tuple whose elements are an arbitrary list of tagged elements and a proof that the elements are compatible with the adjacent ones.
(* I have no idea how to do this in Coq, hence the question!
*
* I am going to use pseudomathematical notation. I am not well versed in either
* mathematics or theoretical computer science, so please do not beat me with a
* stick if I say something that is completely bogus!
*
* I want to construct the type
*
* (tes : taggedElementStack, b : proof that P(tes) holds)
*
* where P(tes) is a predicate that is only true when, for every sublist of tes,
* including tes itself, the heads and tails are compatible.
*)
How would I perform the third step in Coq?
Look at your estack, what does it do? Generalize! element is just a relation (A -> A -> Set), tag is just a Set. What do you get?
Inductive RTList {I : Set} (X : Rel I) : Rel I :=
| RTNil : forall {i : I}, RTList X i i
| RTCons : forall {i j k : I}, X i j -> RTList X j k -> RTList X i k.
(Rel ist just a Definition with Rel I = I -> I -> Set.)
Reflexive-transitive closure! That is common, reusable and modular. Or so you'd think.
The only implementation I found in Coq's libs is in Coq.Relations.Relation_Operators, named clos_refl_trans, differently structured and locked into Prop (all according to the docs, didn't try it).
You'll probably have to re-implement that or find a library somewhere. At least, you'll only have to do this once (or up to three times for Set, Prop and Type).
Your other idea will probably be harder to manage. Look at NoDup for something that's similar to your description, you might be able to reuse the pattern. If you really want that. NoDup uses In, which is a function that checks if an element is in a list. The last time I tried using it, I found it considerably harder to solve proofs involving In. You can't just destruct but have to apply helper lemmas, you have to carefully unfold exactly $n levels, folding back is hard etc. etc. I'd suggest that unless it's truly necessary, you'd better stick with data types for Props.