I have an axiom
Parameter set : Type.
Parameter IN : set->set->Prop.
Axiom AXIOM_OF_SUBSETS :
forall prop x, exists y, forall u,
IN u y <-> IN u x /\ (prop u)
.
Now I would like to build an empty set out of this, like
Definition EMPTYSET : set.
Check (AXIOM_OF_SUBSETS (fun _ : set => False) x).
The result of Check is:
AXIOM_OF_SUBSETS (fun _ : set => False) x
: exists y : set,
forall u : set, IN u y <-> IN u x /\ False
Is there a way to define an EMPTYSET in this situation?
I have found a very simple, but dangerous solution for this:
Just change Parameter set : Type. to Parameter set : Prop..
It worked well at least for axioms, lemmas and theorems that I have written so far.
Will this be the right way to resolve the issue for the rest of the program?
For the problem right above, refer to the https://github.com/coq/coq/wiki/Prop_or_Set .
I take it that you want to formalize Zermelo-Fraenkel set theory in Coq. There are two issues with your code:
In order to apply your axiom, you need to have some set lying around. (Your code mentions a variable x that is not defined anywhere.) One popular option is to combine the axiom of subsets with another axiom that guarantees the existence of some set, such as the axiom of infinity. If you go this way, you need to declare this axiom explicitly.
Coq does not allow the axiom of choice by default. As a result, it is not possible to extract a witness of an existence proof, and to define EMPTYSET based on the proof term you gave. You can solve this issue by either assuming the axiom of choice (check singleton_choice in Coq.Logic.ClassicalChoice (https://coq.github.io/doc/master/stdlib/Coq.Logic.ClassicalChoice.html)), or by slightly changing your formulation of your axiom to avoid the existential quantifier.
Axiom set : Type.
Axiom In : set -> set -> Prop.
Axiom comprehension : (set -> Prop) -> set -> set.
Axiom comprehension_spec :
forall prop x u, In u (comprehension prop x) <-> In u x /\ prop u.
Related
So I am still new to coq and MSets are giving me some issues. Here are two functions to compute whether an element is in a list or set, please let me know if you think the set_contains definition is correct or if there is a better way to do it. Thanks for any help.
Require Import MSets ZArith.
Module mset := MSetAVL.Make Positive_as_OT.
Notation pos_set := mset.t.
Definition set_contains (x : positive) (s : pos_set) :=
mset.mem x s.
Fixpoint list_contains (x : positive) (l : list positive) : bool :=
match l with
| nil => false
| y :: l' =>
if Pos.eqb x y then true
else nodelist_contains x l'
end.
Lemma nodelist_nodeset_contains :
forall x (s : pos_set),
(nodelist_contains x (mset.elements s)) = (nodeset_contains x s).
Proof.
induction s.
destruct list_contains.
destruct set_contains.
auto.
It seems that set_contains evaluates to true at the base case after the destructs and i'm not sure why. Would the set not be mset.empty during that stage of the proof?
I also do not know how to work with the mset.In, I have trouble with the base case of this proof, obviously I have the same problem. I want to eventually state:
Lemma nodelist_containsP :
forall x (l : pos_set),
reflect (mset.In x l) (nodeset_contains x l).
In case anyone is interested here is how I did this proof.
intros.
apply iff_reflect.
unfold nodeset_contains.
symmetry.
apply mset.mem_spec.
Qed.
list_contains and set_contains are functions so it does not make sense to try to destruct them. Coq tries to infer what you meant and guesses that you want to case on the value of an expression starting with list_contains and set_contains respectively.
This is not what you want. What you want is to observe the behaviour of the two functions on the same input. And you can do so by inspecting it.
This should send you in the right direction:
destruct s as [mset mset_isok].
induction mset.
+ unfold set_contains, mset.mem.
simpl.
reflexivity.
+ unfold list_contains, set_contains, mset.mem.
simpl.
I've been stuck on a particular predicate logic problem (using Coq) for a long time. I've solved 30-40 predicate logic problems already but with this one I just can't figure it out.
This is the problem:
~all x, (P(x) / (Q(x) -> T(x))) -> ~all x, T(x).
Or in box form
Can anyone send me in the right direction? Thanks!
Edit:
This is the coq code for the problem:
Variables P Q T : D -> Prop.
Theorem pred_015 : ~all x, (P(x) \/ (Q(x) -> T(x))) -> ~all x, T(x).
Proof.
imp_i H.
Qed.
It looks to me like your are using some very old version of Coq.
After adding a missing declaration for D, and replacing all with forall, we get a statement that does not look provable.
However, if I had a set of parentheses, I get a goal that is now provable. See the following code:
Variable D : Set.
Variables P Q T : D -> Prop.
Theorem pred_015 : (~forall x, (P(x) \/ (Q(x) -> T(x)))) -> ~forall x, T(x).
Proof.
Now, I don't think I should be giving the solution to this here, in public, but it's quite easy if you remember that ~H is defined as H -> False.
Using the notion of subsets as predicates,
ℙ : ∀ {b a} → Set a → Set (a ⊔ suc b)
ℙ {b} {a} X = X → Set b
I'd like to consider structures endowed with a predicate on subsets,
record SetWithAPredicate {a c} : Set {!!} where
field
S : Set a
P : ∀ {b} → ℙ {b} S → Set c
This is an ill-formed construction due to the level quantification used in ℙ. Everything works fine when I use S, P as parameters to a module, but I'd like them to be records so that I can form constructions on them and give instances of them.
I've tried a few other things, such as moving the level b of ℙ inside the definition via an existential but then that led to metavaraible trouble. I also tried changing the type of P,
P : ℙ {a} S → Set c
but then I can no longer ask for, say, the empty set to have the property:
P-⊥ : P(λ _ → ⊥)
This is not well typed since Set != Set a ---I must admit, I tried to use Level.lift here, but failed to do so.
More generally, this will also not allow me to express closure properties, such as P is closed under arbitrary unions ---this is what I'm really interested in.
I understand that I can just avoid level polymorphism,
ℙ' : ∀ {a} → Set a → Set (suc zero ⊔ a)
ℙ' {a} X = X → Set
but then simple items such as the largest subset,
ℙ'-⊤ : ∀ {i} {A : Set i} → ℙ' A
ℙ'-⊤ {i} {A} = λ e → Σ a ∶ A • a ≡ e
-- Σ_∶_•_ is just syntax for Σ A (λ a → ...)
will not even typecheck!
Perhaps I did not realise the notion of subset as predicate appropriately ---any advice would be appreciated. Thank-you!
You need to lift b out from P like this
record SetWithAPredicate {a c} b : Set {!!} where
field
S : Set a
P : ℙ {b} S → Set c
Yes, this is ugly and annoying, but that's how it's done in Agda (an example from standard library: _>>=_ is not properly universe polymorphic). Lift can help sometimes, but it quickly gets out of hand.
Perhaps I did not realise the notion of subset as predicate
appropriately ---any advice would be appreciated.
Your definition is correct, but there is another one, see 4.8.3 in Conor McBride's lecture notes.
I would like to create a quotient type with quotient_type in Isabelle/HOL in which I would left "non-constructed" the non-empty set S and the equivalence relation ≡. The goal is for me to derive generic properties w.r.t. S and ≡ over the quotient-lifted set S/≡. In this way, it would be interesting that Isabelle/HOL accepts dependent types... But I was told that was not possible.
Hence, I tried this
(* 1. Defining an arbitrary set and its associated type *)
consts S :: "'a set"
typedef ('a) inst = "{ x :: 'a. ¬ S = ({} :: 'a set) ⟶ x ∈ S}" by(auto)
(* 2. Defining the equivalence relation *)
definition equiv :: "'a ⇒ 'a ⇒ bool" where
"equiv x y = undefined"
(* here needs a property of equivalence relationship... *)
(* 3. Defining the quotiented set *)
quotient_type ('a) quotiented_set = "('a inst × 'a inst)" / "equiv"
(* Hence, impossible end proof here... *)
Is this formalization, there appears to be two problems
I don't think this is the cleanest way to define an arbitrary set S as I can't specify it to be non-empty...
I can't define an arbitrary equivalence relation equiv with the definition nor the fun commands as they only allow me define "constructive-strongly normalizing-inductive" definitions only... And yet, I want to say that I just have some function equiv that satisfies properties of equivalence (reflexivity, symmetry, transitivity).
Do you have any idea ? Thanks.
HOL types cannot depend on values. So if you want to define a quotient type for an arbitrary non-empty set S and equivalence relation equiv using quotient_type, the arbitrary part must stay at the meta-level. Thus, S and equiv can either be axiomatized or defined such that you can convince yourself that you really have captured the desired notion of arbitrary.
If you axiomatize S and equiv, then you yourself are responsible that the axioms are consistent with the other axioms of HOL. You can do that with the command axiomatization as in
axiomatization S :: "'a set" where S_not_empty: "S ≠ {}"
For Isabelle/HOL, S is then a fixed constant of which you only know that it is not empty. You will never be able to instantiate S, because the arbitrariness only exists in the set-theoretic interpretation of Isabelle/HOL.
If you do not want to add new axioms, you can use specification instead:
consts S :: "'a set"
specification (S) S_not_empty: "S ≠ {}" by auto
With specification, you have to prove that your axioms are consistent, so there is no danger here. However, S no longer is absolutely arbitrary, because it is defined in terms of the choice operator Eps, as can be seen from the generated theorem S_def.
If you really want to study the theory of quotients within Isabelle/HOL, I recommend that you do not use types, but ordinary sets. There is the quotient operator op // and some theorems in the theory Equiv_Relations which is part of the library.
Using the following as an example
postulate DNE : {A : Set} → ¬ (¬ A) → A
data ∨ (A B : Set) : Set where
inl : A → A ∨ B
inr : B → A ∨ B
-- Use double negation to prove exclude middle
classical-2 : {A : Set} → A ∨ ¬ A
classical-2 = λ {A} → DNE (λ z → z (inr (λ x → z (inl x)))
I know this is correct, purely because of how agda works, but I am new to this language and can't get my head around how its syntax works, I would appreciate if anyone can walk me through what is going on, thanks :)
I have experience in haskell, although that was around a year ago.
Let's start with the postulate. The syntax is simply:
postulate name : type
This asserts that there exists some value of type type called name. Think of it as axioms in logic - things that are defined to be true and are not be questioned (by Agda, in this case).
Next up is the data definition. There's a slight oversight with the mixfix declaration so I'll fix it and explain what it does. The first line:
data _∨_ (A B : Set) : Set where
Introduces a new type (constructor) called _∨_. _∨_ takes two arguments of type Set and then returns a Set.
I'll compare it with Haskell. The A and B are more or less equivalent to a and b in the following example:
data Or a b = Inl a | Inr b
This means that the data definition defines a polymorphic type (a template or a generic, if you will). Set is the Agda equivalent of Haskell's *.
What's up with the underscores? Agda allows you to define arbitrary operators (prefix, postfix, infix... usually just called by a single name - mixfix). The underscores just tell Agda where the arguments are. This is best seen with prefix/postfix operators:
-_ : Integer → Integer -- unary minus
- n = 0 - n
_++ : Integer → Integer -- postfix increment
x ++ = x + 1
You can even create crazy operators such as:
if_then_else_ : ...
Next part is definition of the data constructors itself. If you've seen Haskell's GADTs, this is more or less the same thing. If you haven't:
When you define a constructor in Haskell, say Inr above, you just specify the type of the arguments and Haskell figures out the type of the whole thing, that is Inr :: b -> Or a b. When you write GADTs or define data types in Agda, you need to specify the whole type (and there are good reasons for this, but I won't get into that now).
So, the data definition specifies two constructors, inl of type A → A ∨ B and inr of type B → A ∨ B.
Now comes the fun part: first line of classical-2 is a simple type declaration. What's up with the Set thing? When you write polymorphic functions in Haskell, you just use lower case letters to represent type variables, say:
id :: a -> a
What you really mean is:
id :: forall a. a -> a
And what you really mean is:
id :: forall (a :: *). a -> a
I.e. it's not just any kind of a, but that a is a type. Agda makes you do this extra step and declare this quantification explicitly (that's because you can quantify over more things than just types).
And the curly braces? Let me use the Haskell example above again. When you use the id function somewhere, say id 5, you don't need to specify that a = Integer.
If you used normal paretheses, you'd have to provide the actual type A everytime you called classical-2. However, most of the time, the type can be deduced from the context (much like the id 5 example above), so for those cases, you can "hide" the argument. Agda then tries to fill that in automatically - and if it cannot, it complains.
And for the last line: λ x → y is the Agda way of saying \x -> y. That should explain most of the line, the only thing that remains are the curly braces yet again. I'm fairly sure that you can omit them here, but anyways: hidden arguments do what they say - they hide. So when you define a function from {A} to B, you just provide something of type B (because {A} is hidden). In some cases, you need to know the value of the hidden argument and that's what this special kind of lambda does: λ {A} → allows you to access the hidden A!