I know that in maude you can define an operation in one of the following ways:
op operation_: Nat -> Bool . // for 1 operands
op _operation_: Nat Nat -> Bool . // for 2 operands
But is there a way to define the operataion such that it will have more operands?
I guess the ternary conditional opertator (from the Basic Maude) should be a good example: "the presence of underscores in a function name imply that we are using mixfix. The idea is that each argument of the function will replace one of the underscores. For example, consider
op if_then_else_fi : Bool Nat Nat -> Nat .
We could then apply this operator like this:
if B then X else Y fi
where B is a Boolean, and X and Y are Nats."
No limits on operator arity is mentioned in manual (read pp.33-35 to embrace the full power of operator declaration), so
op _ _operation_ _ _: Nat Nat Nat Nat Nat -> Bool . // for 5 operands
should be ok too. I guess at some point you should hit implementation specific, platform, or memory limit.
Related
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.
Why is the following a correct implementation of natural numbers?
mod PEANO-NAT is
sort Nat .
op zero : -> Nat .
op succ : Nat -> Nat .
op plus : Nat Nat -> Nat .
vars N M : Nat .
eq plus(zero, M) = M .
eq plus(succ(N), M) = succ(plus(N, M)) .
endm
in particular I am having a hard time understanding the last two lines nad how they make sure natural numbers are defined correctly. Any help
A better question could be: Why is this definition of the Addition in the Natural Numbers correct?
To answer that question, we must prove that with those two equations, the Addition is a Commutative Monoid. That means: a + b = b + a.
You can try to do that using induction, for the base case and for the inductive step.
Give it a try. I am happy to help.
Is there a way to define subtype relationship in Coq?
I read about subset typing, in which a predicate is used to determine what goes into the subtype, but this is not what I am aiming for. I just want to define a theory in which there is a type (U) and another type (I), which is subtype of (U).
There is no true subtyping in Coq (except for universe subtyping, which is probably not what you want). The closest alternative is to use coercions, which are functions that the Coq type checker inserts automatically whenever it is expecting an element of one type but finds an element of another type instead. For instance, consider the following coercion from booleans to natural numbers:
Definition nat_of_bool (b : bool) : nat :=
if b then 1 else 0.
Coercion nat_of_bool : bool >-> nat.
After running this snippet, Coq uses nat_of_bool to convert bool to nat, as shown here:
Check true + 3.
(* true + 3 : nat *)
Thus, bool starts behaving almost as if it were a subtype of nat.
Though nat_of_bool does not appear here, it is just being hidden by Coq's printer. This term is actually the same thing as nat_of_bool true + 3, as we can see by asking Coq to print all coercions:
Set Printing Coercions.
Check true + 3.
(* nat_of_bool true + 3 : nat *)
The :> symbol you had asked about earlier, when used in a record declaration, is doing the same thing. For instance, the code
Record foo := Foo {
sort :> Type
}.
is equivalent to
Record foo := Foo {
sort : Type
}.
Coercion sort : foo >-> Sortclass.
where Sortclass is a special coercion target for Type, Prop and Set.
The Coq user manual describes coercions in more detail.
I've trouble understanding the (point of the) gauntlet one has to pass to bypass the uniform inheritance condition (UIC). Per the instruction
Let /.../ f: forall (x₁:T₁)..(xₖ:Tₖ)(y:C u₁..uₙ), D v₁..vₘ be a
function which does not verify the uniform inheritance condition. To
declare f as coercion, one has first to declare a subclass C' of C
/.../
In the code below, f is such a function:
Parameter C: nat -> Type.
Parameter D: nat -> Prop.
Parameter f: forall {x y}(z:C x), D y.
Parameter f':> forall {x y}(z:C x), D y. (*violates uic*)
Print Coercions. (* #f' *)
Yet I do not have to do anything except putting :> to declare it as a coercion. Maybe the gauntlet will somehow help to avoid breaking UIC? Not so:
Definition C' := fun x => C x.
Fail Definition Id_C_f := fun x d (y: C' x) => (y: C d). (*attempt to define Id_C_f as in the manual*)
Identity Coercion Id_C_f: C' >-> C.
Fail Coercion f: C' >-> D. (*Cannot recognize C' as a source class of f*)
Coercion f'' {x y}(z:C' x): D y := f z. (*violates uic*)
Print Coercions. (* #f' #f'' Id_C_f *)
The question: What am I missing here?
I've trouble understanding the (point of the) gauntlet one has to pass to bypass the uniform inheritance condition (UIC).
Intuitively, the uniform inheritance condition says (roughly) "it's syntactically possible to determine every argument to the coercion function just from the type of the source argument".
The developer that added coercions found it easier (I presume) to write the code implementing coercions if the uniform inheritance condition is assumed. I'm sure that a pull request relaxing this constraint and correctly implementing more general coercions would be welcomed!
That said, note that there is a warning message (not an error message) when you declare a coercion that violates the UIC. It will still add it to the table of coercions. Depending on your version of Coq, the coercion might never trigger, or you might get an error message at type inference time when the code applying the coercion builds an ill-typed term because it tries to apply the coercion assuming the UIC holds when it actually doesn't, or (in older versions of Coq) you can get anomalies (see, e.g., bug reports #4114, #4507, #4635, #3373, and #2828).
That said, here is an example where Identity Coercions are useful:
Require Import Coq.PArith.PArith. (* positive *)
Require Import Coq.FSets.FMapPositive.
Definition lookup {A} (map : PositiveMap.t A) (idx : positive) : option A
:= PositiveMap.find idx map.
(* allows us to apply maps as if they were functions *)
Coercion lookup : PositiveMap.t >-> Funclass.
Definition nat_tree := PositiveMap.t nat.
Axiom mymap1 : PositiveMap.t nat.
Axiom mymap2 : nat_tree.
Local Open Scope positive_scope. (* let 1 mean 1:positive *)
Check mymap1 1. (* mymap1 1 : option nat *)
Fail Check mymap2 1.
(* The command has indeed failed with message:
Illegal application (Non-functional construction):
The expression "mymap2" of type "nat_tree"
cannot be applied to the term
"1" : "positive" *)
Identity Coercion Id_nat_tree : nat_tree >-> PositiveMap.t.
Check mymap2 1. (* mymap2 1 : option nat *)
Basically, in the extremely limited case where you have an identifier which would be recognized as the source of an existing coercion if you unfolded its type a bit, you can use Identity Coercion to do that. (You can also do it by defining a copy of your existing coercion with a different type signature, and declaring that a coercion too. But then if you have some lemmas that mention one coercion, and some lemmas that mention the other, rewrite will have issues.)
There is one other use case for Identity Coercions, which is that, when your source is not an inductive type, you can use them for folding and not just unfolding identifiers, by playing tricks with Modules and Module Types; see this comment on #3115 for an example.
In general, though, there isn't a way that I know of to bypass the uniform inheritance condition.
I'm quite new with Coq, and I'm trying to define a "generic" indicator function, like this :
Function indicator (x : nat) : bool :=
match x with
| O => false
| _ => true
end.
This one works well.
My problem is that I want an indicator function that returns false for the identity element of any semiring (for which I have a personal definition), not just for the natural number zero, like this :
Function indicator `(S : Semiring) (x : K) : bool :=
match x with
| ident => false
| _ => true
end.
where K is defined in the semiring S as the set and ident is defined in the semiring Sas the identity element.
This one doesn't work. I got the error:
This clause is redundant
with the last line of the match underlined. However, I don't think the error really comes from here. I read that it may come from the line
| ident => false
because ident is a variable, but I don't have more clues.
nat is an inductive type, created from two constructors:
Inductive nat: Set :=
| O : nat
| S : nat -> nat
.
This means that any inhabitant of the nat type is always built by a combination of these 2 constructors.
You can "inspect" this construction by pattern matching, like you did in the first indicator definition.
In the second case, your type K is a type variable (you don't want to have a fix type like nat), so you didn't explain how to build elements of K. Then, when you pattern match, the ident your wrote is just a binder, any name would have had the same effect (and _ too). It has no link to the indent of your semiring. Coq said that the clause is redundant because ident already captured any element of type K, so the _ case is never called.
If you want to write such a function for any type K, you will have to provide a way to compare elements of K (something of the type K -> K -> bool) and use it in your indicator function. I'm not sure about the syntax but you'll have something link:
Record SemiRing : Type := mkSemiRing {
K: Type;
ident : K;
compare : K -> K -> bool;
(* you might need the property that:
forall x y, compare x y = true -> x = y
*)
op1 : K -> K -> K;
op2 : K -> K -> K
(* and all the laws of semiring... *)
}.
Definition indicator (ring: SemiRing) (x: K ring) : bool :=
if compare ring x (ident ring) then true else false.