Prove (p → ¬ q) → ¬ (p ∧ q) in Lean4 - logic

I get as far as this
theorem problem_2 : (p → ¬ q) → ¬ (p ∧ q) := by
intro hp
intro hpw
which gets me to ⊢ False

Not p, or ¬p, is the negation of p. It is defined to be p → False, so if your goal is ¬p you can use intro h to turn the goal into h : p ⊢ False, and if you have hn : ¬p and h : p then hn h : False and (hn h).elim will prove anything. For more information: Propositional Logic.
de Moura, Leonardo, Mario Carneiro et al. “Init.Prelude.” Mathlib4 Docs. Accessed Feb 10, 2023. https://leanprover-community.github.io/mathlib4_docs/Init/Prelude.html#Not.
We can solve the problem as follows:
theorem problem_2 : (p → ¬q) → ¬(p ∧ q) := by
intro hpnq hpq
have hp : p := hpq.1
have hnq : ¬q := hpnq hp
have hq : q := hpq.2
exact hnq hq

Related

Prove that ¬P → ( P → ( P → Q)) is a tautology without using truth tables

I can't find a proper formula for this considering it's almost exclusively made up of implications. Can somebody help me?
EDIT: Sorry, I'm new to this site and still learning to use it. I've tried writing (P → Q) as (¬P ∨ Q) and then applying the distibutive laws but I feel like I've reached a dead end.
P -> q is the same as no(p) OR q
If you replace, in your expression :
P -> (P -> Q) is the same as no(P) OR (no(P) OR Q)
no(P) -> P (P -> (P -> Q)) is the same as no(no(p)) OR (no(P) OR (no(P) OR Q))
which is the same as p OR no(P) OR no(P) OR Q which is always true ( because p or no(p) is always true)
Simply:
!P -> (P -> (P -> Q)) apply implication
P v (!P v (P -> Q))) P v !P is T
T v (...) T v anything is T
T

Translating Coq Definitions to agda?

I'm wondering if there is a systematic way to interpret Coq Definitions as agda programs. I'm working through translating part of programming foundations and am not able to get the tUpdate function to work below. Why is this failing. The coq code is commented.
--Definition total_map (A : Type) := string -> A.
totalMap : Set → Set
totalMap A = String → A
-- Definition t_empty {A : Type} (v : A) : total_map A :=
-- (fun _ => v).
tEmpty : {A : Set} (v : A) → totalMap A
tEmpty = λ v x → v
-- Definition t_update {A : Type} (m : total_map A)
-- (x : string) (v : A) :=
-- fun x' => if eqb_string x x' then v else m x'.
tUpdate : {A : Set} (m : totalMap A) (x : String) (v : A) → Set
tUpdate m x v = λ x' → (if (x == x') then v else m x')
The lambda term produces the below error
(x' : String) → A !=< Set of type Set
when checking that the expression
λ x' → if x == x' then v else m x' has type Set
Is this a correct general schema for doing this translation, e.g., is this translation sound and complete?
Edit:
I realized update was supposed to return a map, but i'm confused as it coq can seemingly infer this while agda can't? I'd still welcome a more general answer to the latter question.
tUpdate : {A : Set} (m : totalMap A) (x : String) (v : A) → totalMap A
tUpdate m x v = λ x' → (if (x == x') then v else m x')
Coq and Agda are both based on very roughly the same dependent type theory, so in theory it would be possible to take the proof term generated by a Coq script and translate it into an Agda program. However, there are many small (and not so small) differences, e.g. Coq's impredicative Prop, cumulativity, differences in the termination checkers, ect, that would make such a translation difficult or impossible.
However, what you're asking for here isn't really an automatic translator but rather a set of rules for translating Coq to Agda by hand. Since many basic features can be mapped one-to-one, this process is much more straightforward. However, any use of tactics in the Coq code you'll either have to translate to an explicit proof term in Agda or write your own Agda reflection macros (since there is no full tactic library for Agda yet).
To answer the specific problem you encountered here: Agda did not try to infer the return type of the tUpdate function because you already specified it to be Set yourself. If you want Agda to infer it for you, you can simply replace the return type with an underscore _ (which works fine in this case):
tUpdate : {A : Set} (m : totalMap A) (x : String) (v : A) → _
tUpdate m x v = λ x' → (if (x == x') then v else m x')

Law of excluded middle in Agda

I've heard the claim that Agda's Martin-Lof Type Theory with Excluded Middle is consistent. How would I go about adding it as a postulate? Also, after Adding LEM, is it then classical first-order logic? By this I mean, do I also have the not (for all) = there exist (not) equivalence? I don't know type theory, so please add additional explanation if you quote any results in type theory.
In MLTT, exists corresponds to a dependent pair which is defined in Data.Product in the standard library. It packages together the existence witness and the proof that it has the right property.
It is not necessary to postulate anything to prove that the negation of an existential statement implies the universal statement of the negated property:
∄⇒∀ : {A : Set} {B : A → Set} →
¬ (∃ λ a → B a) →
∀ a → ¬ (B a)
∄⇒∀ ¬∃ a b = ¬∃ (a , b)
To prove the converse however you do need the law of excluded middle to have a witness appear out of thin air. It is really easy to extend Agda with new postulates, you can simply write (Dec is defined in Relation.Nullary):
postulate LEM : (A : Set) → Dec A
It's always a good thing to remember how to prove double-negation elimination starting from LEM and we will need later on anyway so there it is (case_of_ is defined in Function and explained in README.Case):
¬¬A⇒A : {A : Set} → ¬ (¬ A) → A
¬¬A⇒A {A} ¬¬p =
case LEM A of λ
{ (yes p) → p
; (no ¬p) → ⊥-elim $ ¬¬p ¬p
}
And you can then prove that the negation of a universal statement implies an
existential one like so:
¬∀⇒∃ : {A : Set} {B : A → Set} →
¬ (∀ a → B a) →
∃ λ a → ¬ (B a)
¬∀⇒∃ {A} {B} ¬∀ =
case LEM (∃ λ a → ¬ B a) of λ
{ (yes p) → p
; (no ¬p) → ⊥-elim $ ¬∀ (¬¬A⇒A ∘ ∄⇒∀ ¬p)
}
A gist with all the right imports

How to formalize the definition of likeness/similarity between relations in Coq?

I am reading the book Introduction to Mathematics Philosophy by B.Russell and trying to formalize the definitions. Whereas I got stuck on proving the equivalence between the two definitions of similarity posed in the book.
Here are the text quoted from the book. (context)
1) Defining similarity directly:
We may define two relations P and Q as “similar,” or as having
“likeness,” when there is a one-one relation S whose domain is the
field of P and whose converse domain is the field of Q, and which is
such that, if one term has the relation P to another, the correlate of
the one has the relation Q to the correlate of the other, and vice
versa.
Here's my comprehension of the above text:
Inductive similar {X} (P : relation X) (Q : relation X) : Prop :=
| similar_intro : forall (S : relation X),
one_one S ->
(forall x, field P x <-> domain S x) ->
(forall x y z w, P x y -> S x z -> S y w -> Q z w) ->
(forall x y z w, Q z w -> S x z -> S y w -> P x y) ->
similar P Q.
2) Defining similarity through the concept of 'correlator':
A relation S is said to be a “correlator” or an “ordinal correlator”
of two relations P and Q if S is one-one, has the field of Q for its
converse domain, and is such that P is the relative product of S and Q
and the converse of S.
Two relations P and Q are said to be “similar,” or to have “likeness,”
when there is at least one correlator of P and Q.
My definition to this is:
Inductive correlator {X} (P Q : relation X) : relation X -> Prop :=
| correlator_intro : forall (S : relation X),
one_one S ->
(forall x, field P x <-> domain S x) ->
(forall x y, relative_product (relative_product S Q) (converse S) x y <-> P x y) ->
correlator P Q S.
Inductive similar' {X} (P Q : relation X) : Prop :=
| similar'_intro : forall S, correlator P Q S -> similar' P Q.
But I couldn't prove that similar is equivalent to similar', where did I make the mistake? Thanks a lot.

Odd behavior of setoid_rewrite in Coq

I am having problems with rewriting using the setoid_rewrite tactic. In the following instance declaration, I expect that setoid_rewrite fmapComp would rewrite fmap iso ∘ fmap inv to fmap (iso ∘ inv). However, Coq reports that "no progress was made" during rewriting:
Instance functorsPreserveIsomorphisms
`{C : Cat o η} `{D : Cat u ρ}
{a b : o} {φ : o → u} (F : Functor C D φ) (I : a ≅ b) : φ a ≅ φ b.
Proof.
apply (Build_Isomorphism _ _ _ (φ a) (φ b) (fmap iso) (fmap inv)).
o : Type
η : o → o → Type
C : Cat o η
u : Type
ρ : u → u → Type
D : Cat u ρ
a : o
b : o
φ : o → u
F : Functor C D φ
I : a ≅ b
============================
fmap iso ∘ fmap inv ≡ id (φ a)
I don't understand why setoid_rewrite fails. For reference, the same command works in other contexts using the same terms. For example, it rewrites either side of the following goal to the other:
Lemma worksotherwise
`{C : Cat o η} `{D : Cat u ρ}
{a b : o} {φ : o → u} (F : Functor C D φ) (I : a ≅ b) :
fmap iso ∘ fmap inv ≡ fmap (iso ∘ inv)
o : Type
η : o → o → Type
C : Cat o η
u : Type
ρ : u → u → Type
D : Cat u ρ
a : o
b : o
φ : o → u
F : Functor C D φ
I : a ≅ b
============================
fmap iso ∘ fmap inv ≡ fmap (iso ∘ inv)
It's unclear why setoid_rewrite works in the second case but not the first. For reference, ≡ is equiv and fmap is Proper. Other than that ≅, Functor and Cat are classes, I don't see any other relevant facts. Also, setoid_replace works fine.
This is a shot in the dark without seeing the whole development, but sometimes, when you can't see a difference, it means that there's a difference in a part you don't see. Namely, implicit arguments.
For example, you might have an implicit argument somewhere that appears identically in two locations in the working proof attempt, and that appears in two distinct but interconvertible (or even merely equal) in the non-working proof attempt. Occasionally tactics require identical terms to fire up, whereas interconvertible terms would suffice with the same proof tree, and equal terms would suffice with judicious introduction of eq_refl. When you're working with high-level tactics such as the setoid tactics, it can be difficult to understand what's going on under the hood.
Try comparing the situations under Set Printing Implicit or Set Printing All, or working with No Strict Implicit or No Implicit Arguments for a small part of the proof.

Resources