Last active
January 10, 2022 19:39
-
-
Save hugoferreira/47ecf6b5cc8d942a4b592f8fe0b5eeeb to your computer and use it in GitHub Desktop.
Type-Level Propositional Calculus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Primitives | |
type Theorem = string | |
type Parenthesis<T> = `(${T extends Theorem ? T : never})` | |
type P = 'P' | |
type Q = 'Q' | |
type R = 'R' | |
type And<A extends Theorem, B extends Theorem> = `(${A}&${B})` | |
type Or<A extends Theorem, B extends Theorem> = `(${A}|${B})` | |
type Implies<A extends Theorem, B extends Theorem> = `(${A}->${B})` | |
type Not<A extends Theorem> = `(~${A})` | |
// Axioms | |
const join = <A extends Theorem, B extends Theorem>(_: A, __: B) => <And<A, B>>({}) | |
const sepLeft = <A extends Theorem, B extends Theorem>(_: And<A, B>) => <A>({}) | |
const sepRight = <A extends Theorem, B extends Theorem>(_: And<A, B>) => <B>({}) | |
const doubleTil = <A extends Theorem>(_: A) => <Not<Not<A>>>({}) | |
const doubleTilRev = <A extends Theorem>(_: Not<Not<A>>) => <A>({}) | |
const withPremise = <A extends Theorem, B extends Theorem>(_: (_: A) => B) => <Implies<A, B>>({}) | |
const detach = <A extends Theorem, B extends Theorem>(_: A, __: Implies<A, B>) => <B>({}) | |
const deMorgan = <A extends Theorem, B extends Theorem>(_: And<Not<A>, Not<B>>) => <Not<Or<A, B>>>({}) | |
const contrapos = <A extends Theorem, B extends Theorem>(_: Implies<A, B>) => <Implies<Not<B>, Not<A>>>({}) | |
const contraposRev = <A extends Theorem, B extends Theorem> (_: Implies<Not<B>, Not<A>>) => <Implies<A, B>>({}) | |
const switcherooRev = <A extends Theorem, B extends Theorem>(_: Implies<Not<A>, B>) => <Or<A, B>>({}) | |
// Let's test some theorems (if it compiles, the theorem is true) | |
const t1: '(P->(~(~P)))' = withPremise((p: P) => doubleTil(p)) | |
const t2: Implies<And<P, Q>, And<Q, P>> = withPremise((pq: And<P, Q>) => join(sepRight(pq), sepLeft(pq))) | |
const t3: Implies<P, Implies<Q, And<P, Q>>> = withPremise((p: P) => withPremise((q: Q) => join(p, q))) | |
const theorem4: '(((P->Q)&((~P)->Q))->Q)' = | |
withPremise((premise: And<Implies<P, Q>, Implies<Not<P>, Q>>) => { | |
const a1 = sepLeft(premise) | |
const a2 = contrapos(a1) | |
const a3 = sepRight(premise) | |
const a4 = contrapos(a3) | |
const a5 = withPremise((premise2: '(~Q)') => { | |
const b1 = detach(premise2, a2) | |
const b2 = detach(premise2, a4) | |
const b3 = join(b1, b2) | |
return deMorgan(b3) | |
}) | |
const a6 = contraposRev(a5) | |
const a7 = withPremise((a: '(~P)') => a) | |
const a8 = switcherooRev(a7) | |
return detach(a8, a6) | |
}) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment