This question is a request for references or explanation.
The main idea is: What if I add every axiom from standard library of Coq?
Will it raise a contradiction or they are well-adjusted to each other?
What are other reliable sources of information about Coq other than a standard library of Coq. (I saw a bunch papers from nineties, eighties. Obviously there are plenty of variants of type theories. Which one is for contemporary Coq? Or should I think "Everything that is known may be found in https://coq.inria.fr/refman/ , in https://sympa.inria.fr/sympa/arc/coq-club/1993-12/ and in standard library.")
(A) Do you know paper or other source where it is proved that some axioms may be properly added to Coq?
Properly here means that the extended system will be a conservative extension of previous OR will be considered to be safe strengthening.
(B) Personally, I am interested in these axioms:
0) ex2sig (is it consistent?)
Axiom ex2sig : forall (A:Type) (P:A->Prop), #ex A P -> #sig A P.
1) LEM
2) Functional extensionality
Axiom functional_extensionality_dep : forall {A} {B : A -> Type},
forall (f g : forall x : A, B x),
(forall x, f x = g x) -> f = g.
3) Choice
Theorem choice :
forall (A B : Type) (R : A->B->Prop),
(forall x : A, exists y : B, R x y) ->
exists f : A->B, (forall x : A, R x (f x)).
4) "Terms-as-Types"
Definition E := Type.
Axiom R : forall x : E, x -> E.
Axiom R_inj : forall (x : E) (a b : x), R x a = R x b -> a = b.
5) Proof-Irrelevance
Axiom proof_irrelevance : forall (P:Prop) (p1 p2:P), p1 = p2.
6) ... (you may recommend your axiom in comments)
e.g. Markov's principle
Parameter P:nat -> Prop.
Theorem M:((forall n,(P n \/ ~ (P n)))/\ ~(forall n, ~(P n)) -> exists n,P n).
But we are not very much interested in Markov's principle.
Because we need some very strong classic theory with LEM(so the Markov principle is proved), with some strongest form of Choice(which will imply LEM), extensionality, etc. (Which axioms can we also add?) (By the way, there are many variants of choice in Coq: relational)
p.s. Shall extensive use of "noncomputational" axioms in Coq be treated as misuse of it? (I think no, but I am not sure.)
Which properties of Coq will I loose after adding the axioms? (you may say both reference and/or opinion)
p.p.s. The question is big and consist of many connected pieces, so every partial answer is welcome.
Related
How does the order of implicit arguments affect idris?
I just read this post and I got curious about MkPair's type signature.
I tried MkPair 10 on REPL and I got
(input):Can't infer argument B to Builtins.MkPair
And this is exactly what I expected. From its type signature Builtins.MkPair : {A : Type} -> {B : Type} -> (a : A) -> (b : B) -> (A, B), I have to pass B(whether it's implicit or explicit) before apply a value for a.
At the same time, I expected q 10 to work, cause its type is q : {A : Type} -> (a : A) -> {B : Type} -> (b : B) -> (A, B) which tells me that I don't need any value for B before I apply a value for A and a.
But it also failed with the same message!
(input):Can't infer argument B to Main.q
What happens to q?
And I have one more question . Before I found that q worked neither, I was gonna ask the reason that Idris compiler prefers MkPair's signature to q's one. MkPair looks unnecessarily eager to me. Why does it demand B too early?
Without any context to guide the compiler, I guess Idris stays true to its eager by default attitude and tries to infer all the implicit arguments that appear before the last "explicit" one specified, before doing automatic partial application.
Note that you can suppress this behavior by placing the expression in an appropriately typed hole:
the ({b : Type} -> b -> (Nat, b)) (q 10)
-- or
r : {b : Type} -> b -> (Nat, b)
r = q 10
I'm trying to perform the following proof based on Finite Maps as defined in CoqExtLib. However, I'm having a problem where the instance of RelDec showing up in the proof is different than the instance that I think is declared.
Require Import ExtLib.Data.Map.FMapAList.
Require ExtLib.Structures.Sets.
Module DSet := ExtLib.Structures.Sets.
Require ExtLib.Structures.Maps.
Module Map := ExtLib.Structures.Maps.
Require Import ExtLib.Data.Nat.
Require Import Coq.Lists.List.
Definition Map k v := alist k v.
Definition loc := nat.
Definition sigma : Type := (Map loc nat).
Lemma not_in_sigma : forall (l l' : loc) (e : nat) (s : sigma),
l <> l' ->
Map.lookup l ((l',e)::s) = Map.lookup l s.
intros. simpl. assert ( RelDec.rel_dec l l' = true -> l = l').
pose (ExtLib.Core.RelDec.rel_dec_correct l l') as i. destruct i.
(*i := RelDec.rel_dec_correct l l' : RelDec.rel_dec l l' = true <-> l >= l'*)
As you can see, I'm trying to use the fact that rel_dec must evaluate to false if its two inputs are not equal. This seems to match the definition given in ExtLib.Data.Nat:
Global Instance RelDec_eq : RelDec (#eq nat) :=
{ rel_dec := EqNat.beq_nat }.
However, in the code I showed above, it's using >= instead of = as the relation that the finite map is parameterized on, so I can't apply the theorem rel_dec_correct.
Why is this happening? How is the instance for RelDec being chosen? Is there something special I need to do when proving theorems about types qualified by typeclasses? How can I get a version of rel_dec_correct that applies to equality, not greater-than?
To resolve this issue you might want to set Debug Typeclasses option:
Set Debug Typeclasses.
assert ( RelDec.rel_dec l l' = true -> l = l').
or, alternatively, use Set Printing Implicit to reveal the instances Coq has picked up.
The latter shows us that it is RelDec_ge as the goal now has the following form:
#RelDec.rel_dec loc ge RelDec_ge l l' = true -> l = l'
Apparently Coq chose the instance which is wrong for your purposes, however you can lock the relation you want like so:
assert ( RelDec.eq_dec l l' = true -> l = l').
Now apply (RelDec.rel_dec_correct l l'). resolves the goal, but pose won't work, since there is no information that would tie the goal to a useful instance. The pose tactic would just find an instance of RelDec nat <rel> (you can list all of them with this vernacular: Print Instances RelDec.RelDec.).
There is a very nice tutorial on typeclasses by B.C. Pierce you might want to have a look at.
The third chapter of CPDT briefly discusses why negative inductive types are forbidden in Coq. If we had
Inductive term : Set :=
| App : term -> term -> term
| Abs : (term -> term) -> term.
then we could easily define a function
Definition uhoh (t : term) : term :=
match t with
| Abs f => f t
| _ => t
end.
so that the term uhoh (Abs uhoh) would be non-terminating, with which "we would be able to prove every theorem".
I understand the non-termination part, but I don't get how we can prove anything with it. How would one prove False using term as defined above?
Reading your question made me realize that I didn't quite understand Adam's argument either. But inconsistency in this case results quite easily from Cantor's usual diagonal argument (a never-ending source of paradoxes and puzzles in logic). Consider the following assumptions:
Section Diag.
Variable T : Type.
Variable test : T -> bool.
Variables x y : T.
Hypothesis xT : test x = true.
Hypothesis yF : test y = false.
Variable g : (T -> T) -> T.
Variable g_inv : T -> (T -> T).
Hypothesis gK : forall f, g_inv (g f) = f.
Definition kaboom (t : T) : T :=
if test (g_inv t t) then y else x.
Lemma kaboom1 : forall t, kaboom t <> g_inv t t.
Proof.
intros t H.
unfold kaboom in H.
destruct (test (g_inv t t)) eqn:E; congruence.
Qed.
Lemma kaboom2 : False.
Proof.
assert (H := #kaboom1 (g kaboom)).
rewrite -> gK in H.
congruence.
Qed.
End Diag.
This is a generic development that could be instantiated with the term type defined in CPDT: T would be term, x and y would be two elements of term that we can test discriminate between (e.g. App (Abs id) (Abs id) and Abs id). The key point is the last assumption: we assume that we have an invertible function g : (T -> T) -> T which, in your example, would be Abs. Using that function, we play the usual diagonalization trick: we define a function kaboom that is by construction different from every function T -> T, including itself. The contradiction results from that.
I'm using the mathematical toolkit in HOL-Z to discharge some Isabelle predicates. specifically I'm using the partial function definition to define some of the relations in a Z specification that I'm writing, where I convert the schema's to Specification statements so that I can generate simple HOL predicates.
definitions from HOL-Z toolkit
type_synonym ('a,'b) lts = "('a*'b) set" (infixr "<=>" 20)
prodZ ::"['a set,'b set] => ('a <=> 'b) " ("_ %x _" [81,80] 80)
"a %x b" == "a <*> b"
rel ::"['a set, 'b set] => ('a <=> 'b) set" ("_ <--> _" [54,53] 53)
rel_def : "A <--> B == Pow (A %x B)"
partial_func ::"['a set,'b set] => ('a <=> 'b) set" ("_ -|-> _" [54,53] 53)
partial_func_def : "S -|-> R ==
{f. f:(S <--> R) & (! x y1 y2. (x,y1):f & (x,y2):f --> (y1=y2))}"
rel_appl :: "['a<=>'b,'a] => 'b" ("_ %^ _" [90,91] 90)
rel_appl_def : "R %^ x == (#y. (x,y) : R)"
When I write the following within a predicate:
FORALL x. balance %^ x = Bbalance %^ x
where balance and Bbalance are both partial functions(in Z), of the form ('a <=> 'b) in Isabelle, I assume it behaves fine.
How can I define another function where I say that the two partial functions are totally disjoint for all 'x' . I mean the relational application of the same value on two partial functions 'balance' and 'Bbalance' NEVER produce the same value. something like...
FORALL x. balance %^ x \noteq Bbalance %^ x
sorry for the poor explanation. we learn through expert advice :).
Your rel_appl_def rule makes use of the epsilon function. According to the Stanford Encyclopedia of Philosophy (SEP)(*) in his Hamburg lecture in 1921 (1922), Hilbert first presented the idea of using choice functions to deal with the principle of the excluded middle in a formal system for arithmetic.
The governing axiom of the epsilon function reads as follows:
(A x) --> (A (# A))
In classical logic, because of ex falso quodlibet, if (A x) fails, (# A) can take any interpretation. This means that your rel_appl_def rule gives any value when you supply an argument x that is not in the domain dom R.
So probably what you want to use as equality would be the following boolean function (^) on two partial functions:
f ^ g = (dom f = dom g) & (!x. x : dom f --> f %^ x = g %^ x)
What I cannot understand when SEP writes, the second, of perhaps greater current interest, is the use of the epsilon-operator in the theorem-proving systems HOL and Isabelle, where the expressive power of epsilon-terms yields significant practical advantages.
I have seen a much simpler treatment of partial functions in practice, namely using the option type. So a partial function f belongs simply to a type A => B option. But when you cannot change the types in your project, it is probably wiser to seek the equality that fits your requirements, the above definition could be a candidate.
Bye
(*)
The Epsilon Calculus, Jeremy Avigad and Richard Zach
First published Fri May 3, 2002; substantive revision Wed Nov 27, 2013
http://plato.stanford.edu/entries/epsilon-calculus/
Can the following polymorphic functions
let id x = x;;
let compose f g x = f (g x);;
let rec fix f = f (fix f);; (*laziness aside*)
be written for types/type constructors or modules/functors? I tried
type 'x id = Id of 'x;;
type 'f 'g 'x compose = Compose of ('f ('g 'x));;
type 'f fix = Fix of ('f (Fix 'f));;
for types but it doesn't work.
Here's a Haskell version for types:
data Id x = Id x
data Compose f g x = Compose (f (g x))
data Fix f = Fix (f (Fix f))
-- examples:
l = Compose [Just 'a'] :: Compose [] Maybe Char
type Natural = Fix Maybe -- natural numbers are fixpoint of Maybe
n = Fix (Just (Fix (Just (Fix Nothing)))) :: Natural -- n is 2
-- up to isomorphism composition of identity and f is f:
iso :: Compose Id f x -> f x
iso (Compose (Id a)) = a
Haskell allows type variables of higher kind. ML dialects, including Caml, allow type variables of kind "*" only. Translated into plain English,
In Haskell, a type variable g can correspond to a "type constructor" like Maybe or IO or lists. So the g x in your Haskell example would be OK (jargon: "well-kinded") if for example g is Maybe and x is Integer.
In ML, a type variable 'g can correspond only to a "ground type" like int or string, never to a type constructor like option or list. It is therefore never correct to try to apply a type variable to another type.
As far as I'm aware, there's no deep reason for this limitation in ML. The most likely explanation is historical contingency. When Milner originally came up with his ideas about polymorphism, he worked with very simple type variables standing only for monotypes of kind *. Early versions of Haskell did the same, and then at some point Mark Jones discovered that inferring the kinds of type variables is actually quite easy. Haskell was quickly revised to allow type variables of higher kind, but ML has never caught up.
The people at INRIA have made a lot of other changes to ML, and I'm a bit surprised they've never made this one. When I'm programming in ML, I might enjoy having higher-kinded type variables. But they aren't there, and I don't know any way to encode the kind of examples you are talking about except by using functors.
You can do something similar in OCaml, using modules in place of types, and functors (higher-order modules) in place of higher-order types. But it looks much uglier and it doesn't have type-inference ability, so you have to manually specify a lot of stuff.
module type Type = sig
type t
end
module Char = struct
type t = char
end
module List (X:Type) = struct
type t = X.t list
end
module Maybe (X:Type) = struct
type t = X.t option
end
(* In the following, I decided to omit the redundant
single constructors "Id of ...", "Compose of ...", since
they don't help in OCaml since we can't use inference *)
module Id (X:Type) = X
module Compose
(F:functor(Z:Type)->Type)
(G:functor(Y:Type)->Type)
(X:Type) = F(G(X))
let l : Compose(List)(Maybe)(Char).t = [Some 'a']
module Example2 (F:functor(Y:Type)->Type) (X:Type) = struct
(* unlike types, "free" module variables are not allowed,
so we have to put it inside another functor in order
to scope F and X *)
let iso (a:Compose(Id)(F)(X).t) : F(X).t = a
end
Well... I'm not an expert of higher-order-types nor Haskell programming.
But this seems to be ok for F# (which is OCaml), could you work with these:
type 'x id = Id of 'x;;
type 'f fix = Fix of ('f fix -> 'f);;
type ('f,'g,'x) compose = Compose of ('f ->'g -> 'x);;
The last one I wrapped to tuple as I didn't come up with anything better...
You can do it but you need to make a bit of a trick:
newtype Fix f = In{out:: f (Fix f)}
You can define Cata afterwards:
Cata :: (Functor f) => (f a -> a) -> Fix f -> a
Cata f = f.(fmap (cata f)).out
That will define a generic catamorphism for all functors, which you can use to build your own stuff. Example:
data ListFix a b = Nil | Cons a b
data List a = Fix (ListFix a)
instance functor (ListFix a) where
fmap f Nil = Nil
fmap f (Cons a lst) = Cons a (f lst)