I'm trying to define a power function in Coq, and I can't seem to find the relevant module to import:
Require Import Coq.Numbers.NatInt.NZPow.
Definition func (a b : nat) : nat := a+b*2^a.
Gives me the following error:
Unknown interpretation for notation "_ ^ _".
I'm a bit confused, because inside Coq.Numbers.NatInt.NZPow, I see the following description:
Interface of a power function, then its specification on naturals
And also this:
Module Type PowNotation (A : Typ)(Import B : Pow A).
Infix "^" := pow.
End PowNotation.
So what am I missing?
(TLDR; You can to just Require Import Nat. to get the pow definition and notation for nat.
Require Import Nat.
Definition func (a b : nat) : nat := a+b*2^a.
)
The problem is that you are trying to use a module type instead of a module.
The abstract interfaces of NZPow need to be instantiated for the specific types. In the case of nat it is already done in the library in NPeano. It is just taking the already defined stuff in the "old" PeanoNat.Nat, so its very short. Btw, note the deprecation warning...
(** This file is DEPRECATED ! Use [PeanoNat] (or [Arith]) instead. *)
(** [PeanoNat.Nat] already implements [NAxiomSig] *)
Module Nat <: NAxiomsSig := Nat.
Anyway, if you insist on using this, you should import NPeano which is a module that concretely implements the NAxsiomsSig module type for nat. It will just give you the same functions you get when you do Require Import Nat. You can see they are really definitionally the same function with
Require Import Init.Nat.
Require Import NPeano.
Check eq_refl: Init.Nat.add = NPeano.Nat.add.
(The Numbers seem to not have gotten much attention since 2011, so perhaps you should use something more maintained for your work. OTOH, natural numbers have also been around unchanged for the last 13 billion plus years, so...)
All the NZ modules contain axiomatizations. They specify the properties of functions like pow without actually defining them. They do this by using Modules. A Module is a collection of definitions, notations, etc., and the names and types of those definitions etc. form a Module Type. You can "open" a Module and use whatever's inside by Importing it, but to do that you need to have a module of the correct type in the first place.
Pow A is the type of implementations of pow : A -> A -> A, and PowNotation is the type of modules that contain the notation Infix "^" := pow. If you have a Module that has type (or supertype!) PowNotation, you can Import that module to get at that notation. But, again, since the NZ modules are just axiomatizations, they don't give you such a module and so you haven't imported anything that gives you that notation. You can directly import an actual implementation:
Require Import PeanoNat.
(* The module Nat has type Pow nat, witnessed by Nat.pow : nat -> nat -> nat
however, it does not have type Pow' nat, so it doesn't actually contain
Infix "^" := pow.
The "^" notation is just coming from PeanoNat itself. *)
Definition func (a b : nat) : nat := a+b*2^a.
Or you can abstract over the number system in use (so it could be unary nats, or the binary naturals, or the integers, or the integers mod some number, etc.), in the same way that all the NZ modules abstract over the number system:
Require Import NZAxioms.
Require Import NZPow.
Module Type NZFunc (Import A : Typ) (Import OT : OneTwo' A) (Import ASM : AddSubMul' A) (Import P : Pow' A).
Definition func (a b : t) : t := a+b*2^a.
(* t means A.t, and can be many things depending on the final implementation of this module type *)
(* 2 comes from OT, + from ASM, and ^ from P *)
End NZFunc.
Related
I'm really annoyed by the following goal:
a%:R \is a unit
where a is a nat. The only lemma that seems to help is unitrE, but then it seems impossible to simplify further. This goal should be solvable. Can someone explain how to coerce this to a field type so I can use unitfE which I can easily work with.
you can only use unitfE if the structure you work with is a field. Otherwise you need to deal with the characteristic ([char R]) of your ring.
What is your structure?
If you assume that a is non-zero (which makes sense, to have an inverse), then you can do this:
From mathcomp Require Import all_ssreflect all_algebra.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Open Scope ring_scope.
Import GRing.Theory.
Variable (R : numFieldType).
Variable (a : nat).
Definition a' : R := a%:R.
Hypothesis nea'0 : a' != 0.
Lemma a'unit : a' \is a GRing.unit.
Proof. by rewrite unitfE nea'0. Qed.
Playing with nostutter excersizes I found another odd behaviour. Here is the code:
Inductive nostutter {X:Type} : list X -> Prop :=
| ns_nil : nostutter []
| ns_one : forall (x : X), nostutter [x]
| ns_cons: forall (x : X) (h : X) (t : list X), nostutter (h::t) -> x <> h -> nostutter (x::h::t).
Example test_nostutter_manual: not (nostutter [3;1;1;4]).
Proof.
intro.
inversion_clear H.
inversion_clear H0.
unfold not in H2.
(* We are here *)
specialize (H2 eq_refl).
apply H2.
Qed.
Status after unfold is this:
1 subgoal (ID 229)
H1 : 3 <> 1
H : nostutter [1; 4]
H2 : 1 = 1 -> False
============================
False
When I run specialize (H2 eq_refl). inside IndProp.v that loads other Logical foundations files, it works. Somehow it understands that it needs to put "1" as a parameter. Header of IndProp.v is this:
Set Warnings "-notation-overridden,-parsing".
From LF Require Export Logic.
Require Import String.
Require Coq.omega.Omega.
When I move the code into another file "nostutter.v", this same code gives an expected error:
The term "eq_refl" has type "RelationClasses.Reflexive Logic.eq" while
it is expected to have type "1 = 1".
Header of nostutter.v:
Set Warnings "-notation-overridden,-parsing".
Require Import List.
Import ListNotations.
Require Import PeanoNat.
Import Nat.
Local Open Scope nat_scope.
I have to explicitly add a parameter to eq_refl: specialize (H2 (eq_refl 1)).
I think it's not related specifically to specialize. What is it? How to fix?
The problem is importing PeanoNat.Nat.
When you import PeanoNat, the module type Nat comes into scope, so importing Nat brings in PeanoNat.Nat. If you meant to import Coq.Init.Nat, you'll either have to import it before importing PeanoNat, or import it with Import Init.Nat..
Why does importing PeanoNat.Nat cause trouble in this case?
Arith/PeanoNat.v (static link) contains the module1 Nat. Inside that module, we find2 the unusual looking line
Include NBasicProp <+ UsualMinMaxLogicalProperties <+ UsualMinMaxDecProperties.
All this means is that each of NBasicProp, UsualMinMaxLogicalProperties and UsualMinMaxDecProperties are included, which in turn means that everything defined in those modules is included in the current module. Separating this line out into three Include commands, we can figure out which one is redefining eq_refl. It turns out to be NBasicProp, which is found in this file (static link). We're not quite there yet: the redefinition of eq_refl isn't here. However, we see the definition of NBasicProp in terms of NMaxMinProp.
This leads us to NMaxMin.v, which in turn leads us to NSub.v, which leads us to NMulOrder.v, which leads us to NAddOrder.v, which leads us to NOrder.v, which leads us to NAdd.v, which leads us to NBase.v, ...
I'll cut to the chase here. Eventually we end up in Structures/Equality.v (static link) with the module BackportEq which finally gives us our redefinition of eq_refl.
Module BackportEq (E:Eq)(F:IsEq E) <: IsEqOrig E.
Definition eq_refl := #Equivalence_Reflexive _ _ F.eq_equiv.
Definition eq_sym := #Equivalence_Symmetric _ _ F.eq_equiv.
Definition eq_trans := #Equivalence_Transitive _ _ F.eq_equiv.
End BackportEq.
The way this is defined, eq_refl (without any arguments) has type Reflexive eq, where Reflexive is the class
Class Reflexive (R : relation A) :=
reflexivity : forall x : A, R x x.
(found in Classes/RelationClasses.v)
So that means that we'll always need to supply an extra argument to get something of type x = x. There are no implicit arguments defined here.
Why is importing modules like PeanoNat.Nat generally a bad idea?
If the wild goose chase above wasn't convincing enough, let me just say that modules like this one, which extend and import other modules and module types, are often not meant to be imported. They often have short names (like N, Z or Nat) so any theorem you want to use from them is easily accessible without having to type out a long name. They usually have a long chain of imports and thus contain a vast number of items. If you import them, now that vast number of items is polluting your global namespace. As you saw with eq_refl, that can cause unexpected behavior with what you thought was a familiar constant.
Most of the modules encountered in this adventure are of the "module type/functor" variety. Suffice to say, they're difficult to understand fully, but a short guide can be found here.
My sleuthing was done by opening files in CoqIDE and running the command Locate eq_refl. (or better yet, ctrl+shift+L) after anything that might import from elsewhere. Locate can also tell you where a constant was imported from. I wish there were an easier way to see the path of imports in module types, but I don't think so. You could guess that we'd end up in Coq.Classes.RelationClasses based on the type of the overwritten eq_refl, but that isn't as precise.
I have a module and I need to specialize one of its argument. I want to use natural numbers instead of arbitrary UsualDecidableTypeFull. How can I obtain such behaviour in Coq?
I defined some module:
Module PRO2PRE_mod
(SetVars FuncSymb PredSymb PropSymb: UsualDecidableTypeFull).
(* ... *)
End PRO2PRE_mod.
Then I specialized the last of the arguments PropSymb.
Require Import Arith.PeanoNat.
Module m2 : UsualDecidableTypeFull.
Definition t:=nat.
Definition eq := #eq nat.
Definition eq_refl:=#eq_refl nat.
Definition eq_sym:=#eq_sym nat.
Definition eq_trans:=#eq_trans nat.
Definition eq_equiv:Equivalence eq := Nat.eq_equiv.
Definition eq_dec := Nat.eq_dec.
Definition eqb:=Nat.eqb.
Definition eqb_eq:=Nat.eqb_eq.
End m2.
This module needs specialization of PropVars:
Module SWAP_mod
(SetVars FuncSymb PredSymb : UsualDecidableTypeFull).
Module PRE := PRO2PRE_mod SetVars FuncSymb PredSymb m2.
Import PRE.
Theorem test : m2.t.
try exact 0. (* ERROR HERE! *)
Abort.
End SWAP_mod.
How to use theorems about natural numbers inside the last module? (I think I don't understand something about using modules... Maybe we need somehow to coerce the type 'm2.t' to the type 'nat'?)
Indeed, the use of : UsualDecidableTypeFull in the definition of m2 hides completely the implementation details of m2. From the outside, m2.t is an unknown type.
Sometimes, this is exactly what you want. For example, you may want to abstract away a type defined in a module so that the users cannot manipulate values of this type without using the functions that you gave to them in the module. You can thus ensure that they will not break some invariants.
However, in your case, you need to remember that m2.t is actually nat, you have at least these two options:
Make the interface transparent with Module m2 <: UsualDecidableTypeFull. When using this, Coq just verifies that the definition of the module complies with the signature, but does not hide the content of the module.
If you still want to hide part of the module, you can also use
Module m2 : UsualDecidableTypeFull with Definition t := nat.
In this case, from the outside, m2.t is known to be nat, but the other fields of m are masked. For instance, the body of m2.eqb is hidden.
I am a programmer, but an ultra-newbie to Coq, and have tried to figure out the tutorials without much success. My question is very simple: How does one define an ordered pair (of natural numbers) in Coq?
Here was my attempt:
Variable node1 : nat.
Variable node2 : nat.
Inductive edge : type := node1 -> node2.
(Note that "edge" is the name I am using for ordered pair.) The third line gives a syntax error, suggesting that I need a '.' in the sentence somewhere.
I don't know what to do. Any help would be great! (Also, is there a tutorial that helps teach very basic Coq concepts better than the ones that are easily seen given a Google search for "Coq Tutorial" ?)
You can do this simply enough by just using a Coq definition:
Definition ordered_pair := (nat * nat) % type.
This introduces ordered_pair as a synonym for (nat * nat) % type (note that the % type is required to get Coq to interpret * in the scope of types, rather than naturals). The real power is in the use of *:
Inductive prod (A B:Type) : Type :=
pair : A -> B -> prod A B.
(From http://coq.inria.fr/stdlib/Coq.Init.Datatypes.html)
You get all the necessary elimination principles, etc... from there.
I defined a module type in one file called A.v
Module Type WeakPair.
...
End WeakPair.
Module WeakPairProps (Import WP : WeakPair).
Lemma Weak_A ....
End WeakPairProps.
Then I want to define another file B.v that can use the Lemma in WeakPairProps for example : Weak_A.
Because WeakPairProps is not a module type so I do not know how to write a module that can reuse the lemma in WeakPairProps.
First you need to define a module that implements the module type WeakPair :
Module WeakPairImpl <: WeakPair.
(* stuff goes here *)
End WeakPairImpl.
Now you can instantiate the functor WeakPairProps:
Module WeakPairPropsInst := WeakPairProps(WeakPairImpl).
You are now able to refer to the lemma:
WeakPairPropsInst.lemma
You can import WeakPairPropsInst if you desire not to use qualified names.