Copyright | (c) Matt Noonan 2018 |
---|---|
License | BSD-style |
Maintainer | matt.noonan@gmail.com |
Portability | portable |
Safe Haskell | None |
Language | Haskell2010 |
Synopsis
- data TRUE
- data FALSE
- data And p q
- type (&&) p q = p `And` q
- type (∧) p q = p `And` q
- type (/\) p q = p `And` q
- data Or p q
- type (||) p q = p `Or` q
- type (∨) p q = p `Or` q
- type (\/) p q = p `Or` q
- data Implies p q
- type (-->) p q = p `Implies` q
- data Not p
- data ForAll x p
- data Exists x p
- true :: Proof TRUE
- noncontra :: Proof (Not (p && Not p))
- introAnd :: Proof p -> Proof q -> Proof (p && q)
- introAnd' :: Proof q -> Proof p -> Proof (p && q)
- introOrL :: Proof p -> Proof (p || q)
- introOrR :: Proof q -> Proof (p || q)
- introImpl :: (Proof p -> Proof q) -> Proof (p --> q)
- introNot :: (Proof p -> Proof FALSE) -> Proof (Not p)
- contrapositive :: (Proof p -> Proof FALSE) -> Proof (Not p)
- contradicts :: Proof p -> Proof (Not p) -> Proof FALSE
- contradicts' :: Proof (Not p) -> Proof p -> Proof FALSE
- introUniv :: (forall c. Proof (p c)) -> Proof (ForAll x (p x))
- introEx :: Proof (p c) -> Proof (Exists x (p x))
- elimAndL :: Proof (p && q) -> Proof p
- elimAndR :: Proof (p && q) -> Proof q
- elimOr :: (Proof p -> Proof r) -> (Proof q -> Proof r) -> Proof (p || q) -> Proof r
- elimOrL :: (Proof p -> Proof r) -> Proof (p || q) -> (Proof q -> Proof r) -> Proof r
- elimOrR :: (Proof q -> Proof r) -> Proof (p || q) -> (Proof p -> Proof r) -> Proof r
- elimImpl :: Proof p -> Proof (p --> q) -> Proof q
- modusPonens :: Proof (p --> q) -> Proof p -> Proof q
- modusTollens :: Proof (p --> q) -> Proof (Not q) -> Proof (Not p)
- absurd :: Proof FALSE -> Proof p
- elimUniv :: Proof (ForAll x (p x)) -> Proof (p c)
- elimEx :: (forall c. Proof (p c) -> Proof q) -> Proof (Exists x (p x)) -> Proof q
- class Classical
- classically :: (Classical => Proof p) -> Proof p
- lem :: Classical => Proof (p || Not p)
- contradiction :: Classical => (Proof (Not p) -> Proof FALSE) -> Proof p
- elimNot :: Classical => (Proof (Not p) -> Proof FALSE) -> Proof p
- elimNotNot :: Classical => Proof (Not (Not p)) -> Proof p
- firstAnd :: (Proof p -> Proof p') -> Proof (p && q) -> Proof (p' && q)
- secondAnd :: (Proof q -> Proof q') -> Proof (p && q) -> Proof (p && q')
- bimapAnd :: (Proof p -> Proof p') -> (Proof q -> Proof q') -> Proof (p && q) -> Proof (p' && q')
- firstOr :: (Proof p -> Proof p') -> Proof (p || q) -> Proof (p' || q)
- secondOr :: (Proof q -> Proof q') -> Proof (p || q) -> Proof (p || q')
- bimapOr :: (Proof p -> Proof p') -> (Proof q -> Proof q') -> Proof (p || q) -> Proof (p' || q')
- lmapImpl :: (Proof p' -> Proof p) -> Proof (p --> q) -> Proof (p' --> q)
- rmapImpl :: (Proof q -> Proof q') -> Proof (p --> q) -> Proof (p --> q')
- dimapImpl :: (Proof p' -> Proof p) -> (Proof q -> Proof q') -> Proof (p --> q) -> Proof (p' --> q')
- mapNot :: (Proof p' -> Proof p) -> Proof (Not p) -> Proof (Not p')
First-order Logic
Logical symbols
data And p q infixl 3 Source #
The conjunction of p
and q
.
Instances
Symmetric (And :: k -> k -> Type) Source # | |
DistributiveR (And :: Type -> k -> Type) (And :: Type -> Type -> Type) Source # | |
DistributiveR (Or :: Type -> k -> Type) (And :: Type -> Type -> Type) Source # | |
DistributiveR (And :: Type -> k -> Type) (Or :: Type -> Type -> Type) Source # | |
DistributiveL (And :: k -> Type -> Type) (And :: Type -> Type -> Type) Source # | |
DistributiveL (Or :: k -> Type -> Type) (And :: Type -> Type -> Type) Source # | |
DistributiveL (And :: k -> Type -> Type) (Or :: Type -> Type -> Type) Source # | |
Associative (And :: Type -> Type -> Type) Source # | |
Defined in Logic.Propositional |
The disjunction of p
and q
.
Instances
Symmetric (Or :: k -> k -> Type) Source # | |
DistributiveR (Or :: Type -> k -> Type) (Or :: Type -> Type -> Type) Source # | |
DistributiveR (Or :: Type -> k -> Type) (And :: Type -> Type -> Type) Source # | |
DistributiveR (And :: Type -> k -> Type) (Or :: Type -> Type -> Type) Source # | |
DistributiveL (Or :: k -> Type -> Type) (Or :: Type -> Type -> Type) Source # | |
DistributiveL (Or :: k -> Type -> Type) (And :: Type -> Type -> Type) Source # | |
DistributiveL (And :: k -> Type -> Type) (Or :: Type -> Type -> Type) Source # | |
Associative (Or :: Type -> Type -> Type) Source # | |
Defined in Logic.Propositional |
Natural deduction
Tautologies
noncontra :: Proof (Not (p && Not p)) Source #
The Law of Noncontradiction: for any proposition P, "P and not-P" is false.
Introduction rules
Introduction rules give the elementary building blocks for creating a formula from simpler ones.
introImpl :: (Proof p -> Proof q) -> Proof (p --> q) Source #
Prove "P implies Q" by demonstrating that, from the assumption P, you can prove Q.
introNot :: (Proof p -> Proof FALSE) -> Proof (Not p) Source #
Prove "not P" by demonstrating that, from the assumption P, you can derive a false conclusion.
contrapositive :: (Proof p -> Proof FALSE) -> Proof (Not p) Source #
contrapositive
is an alias for introNot
, with
a somewhat more suggestive name. Not-introduction
corresponds to the proof technique "proof by contrapositive".
contradicts :: Proof p -> Proof (Not p) -> Proof FALSE Source #
Prove a contradiction from P and "not P".
contradicts' :: Proof (Not p) -> Proof p -> Proof FALSE Source #
contradicts'
is contradicts
with the arguments
flipped. It is useful when you want to partially
apply contradicts
to a negation.
introUniv :: (forall c. Proof (p c)) -> Proof (ForAll x (p x)) Source #
Prove "For all x, P(x)" from a proof of P(*c*) with *c* indeterminate.
introEx :: Proof (p c) -> Proof (Exists x (p x)) Source #
Prove "There exists an x such that P(x)" from a specific instance of P(c).
Elimination rules
Elimination rules give the elementary building blocks for decomposing a complex formula into simpler ones.
elimOr :: (Proof p -> Proof r) -> (Proof q -> Proof r) -> Proof (p || q) -> Proof r Source #
If you have a proof of R from P, and a proof of R from Q, then convert "P or Q" into a proof of R.
elimOrL :: (Proof p -> Proof r) -> Proof (p || q) -> (Proof q -> Proof r) -> Proof r Source #
Eliminate the first alternative in a conjunction.
elimOrR :: (Proof q -> Proof r) -> Proof (p || q) -> (Proof p -> Proof r) -> Proof r Source #
Eliminate the second alternative in a conjunction.
elimImpl :: Proof p -> Proof (p --> q) -> Proof q Source #
Given "P imples Q" and P, produce a proof of Q. (modus ponens)
modusPonens :: Proof (p --> q) -> Proof p -> Proof q Source #
modusPonens
is just elimImpl
with the arguments
flipped. In this form, it is useful for partially
applying an implication.
modusTollens :: Proof (p --> q) -> Proof (Not q) -> Proof (Not p) Source #
Modus tollens lets you prove "Not P" from "P implies Q" and "Not Q".
Modus tollens is not fundamental, and can be derived from other rules:
----- (assumption) p --> q, p --------------------- (modus ponens) Not q, q -------------------------- (contradicts') FALSE ------------------------------------- (not-intro) Not p
We can encode this proof tree as a Proof
to implement
modus_tollens
:
modusTollens :: Proof (p --> q) -> Proof (Not q) -> Proof (Not p) modusTollens impl q' = introNot $ p -> contradicts' q' (modusPonens impl p)
elimUniv :: Proof (ForAll x (p x)) -> Proof (p c) Source #
Given "For all x, P(x)" and any c, prove the proposition "P(c)".
elimEx :: (forall c. Proof (p c) -> Proof q) -> Proof (Exists x (p x)) -> Proof q Source #
Given a proof of Q from P(c) with c generic, and the statement "There exists an x such that P(x)", produce a proof of Q.
Classical logic and the Law of the Excluded Middle
The inference rules so far have all been valid in
constructive logic. Proofs in classical logic are
also allowed, but will be constrained by the
Classical
typeclass.
classically :: (Classical => Proof p) -> Proof p Source #
Discharge a Classical
constraint, by saying
"I am going to allow a classical argument here."
NOTE: The existence of this function means that a proof
should only be considered constructive if it
does not have a Classical
constraint, *and*
it does not invoke classically
.
lem :: Classical => Proof (p || Not p) Source #
The Law of the Excluded Middle: for any proposition P, assert that either P is true, or Not P is true.
contradiction :: Classical => (Proof (Not p) -> Proof FALSE) -> Proof p Source #
Proof by contradiction: this proof technique allows you to prove P by showing that, from "Not P", you can prove a falsehood.
Proof by contradiction is not a theorem of
constructive logic, so it requires the Classical
constraint. But note that the similar technique
of proof by contrapositive (not-introduction) is
valid in constructive logic! For comparison, the two types are:
contradiction :: Classical => (Proof (Not p) -> Proof FALSE) -> Proof p introNot :: (Proof p -> Proof FALSE) -> Proof (Not p)
The derivation of proof by contradiction from the law of the excluded
middle goes like this: first, use the law of the excluded middle to
prove p || Not p
. Then use or-elimination to prove p
for each
alternative. The first alternative is immediate; for the second
alternative, use the provided implication to get a proof of falsehood,
from which the desired conclusion is derived.
contradiction impl = elimOr id (absurd . impl) lem
elimNot :: Classical => (Proof (Not p) -> Proof FALSE) -> Proof p Source #
Alias for contradiction
, to complete the patterns.
elimNotNot :: Classical => Proof (Not (Not p)) -> Proof p Source #
Double-negation elimination. This is another non-constructive
proof technique, so it requires the Classical
constraint.
The derivation of double-negation elimination follows from
proof by contradiction, since "Not (Not p)" contradicts "Not p".
elimNotNot p'' = contradiction (contradicts' p'')
Mapping over conjunctions and disjunctions.
These function names mimic the ones for
(Functor
Bifunctor
Profunctor
).
firstAnd :: (Proof p -> Proof p') -> Proof (p && q) -> Proof (p' && q) Source #
Apply a derivation to the left side of a conjunction.
secondAnd :: (Proof q -> Proof q') -> Proof (p && q) -> Proof (p && q') Source #
Apply a derivation to the right side of a conjunction.
bimapAnd :: (Proof p -> Proof p') -> (Proof q -> Proof q') -> Proof (p && q) -> Proof (p' && q') Source #
Apply derivations to the left and right sides of a conjunction.
firstOr :: (Proof p -> Proof p') -> Proof (p || q) -> Proof (p' || q) Source #
Apply a derivation to the left side of a disjunction.
secondOr :: (Proof q -> Proof q') -> Proof (p || q) -> Proof (p || q') Source #
Apply a derivation to the right side of a disjunction.
bimapOr :: (Proof p -> Proof p') -> (Proof q -> Proof q') -> Proof (p || q) -> Proof (p' || q') Source #
Apply derivations to the left and right sides of a disjunction.
lmapImpl :: (Proof p' -> Proof p) -> Proof (p --> q) -> Proof (p' --> q) Source #
Apply a derivation to the left side of an implication.
rmapImpl :: (Proof q -> Proof q') -> Proof (p --> q) -> Proof (p --> q') Source #
Apply a derivation to the right side of an implication.