prop/lib.rs
1#![deny(missing_docs)]
2#![deny(dead_code)]
3#![feature(marker_trait_attr)]
4#![allow(incomplete_features)]
5#![allow(clippy::type_complexity)]
6
7//! # Prop
8//! Propositional logic with types in Rust.
9//!
10//! A library in Rust for theorem proving with [Intuitionistic Propositional Logic](https://en.wikipedia.org/wiki/Intuitionistic_logic).
11//! Supports theorem proving in [Classical Propositional Logic](https://en.wikipedia.org/wiki/Propositional_calculus).
12//!
13//! - Used in research on [Path Semantics](https://github.com/advancedresearch/path_semantics)
14//! - Brought to you by the [AdvancedResearch Community](https://advancedresearch.github.io/)
15//! - [Join us on Discord!](https://discord.gg/JkrhJJRBR2)
16//!
17//! Abbreviations:
18//!
19//! - IPL: Intuitionistic/Constructive Propositional Logic
20//! - EL: Existential Logic (Excluded Middle of Non-Existence)
21//! - PL: Classical Propositional Logic
22//! - PSI: Path Semantical Intuitionistic/Constructive Propositional Logic
23//! - PSEL: Path Semantical Existential Logic
24//! - PSL: Path Semantical Classical Propositional Logic
25//! - PSQ: Path Semantical Quantum Propositional Logic
26//! - HOOO EP: Higher Order Operator Overloading Exponential Propositions
27//! - MEL: Middle Exponential Logic
28//!
29//! ### Motivation
30//!
31//! [Path Semantics](https://github.com/advancedresearch/path_semantics)
32//! extends dependent types with normal paths and is also used to extend
33//! Classical Propositional Logic with multiple levels of propositions.
34//! It is also used to explore higher dimensional mathematics.
35//! A popular research subject in Path Semantics is [Avatar Extensions](https://advancedresearch.github.io/avatar-extensions/summary.html).
36//!
37//! When researching, in some cases it is useful to figure out whether a proof is
38//! provable in classical logic, but not in constructive logic.
39//! This requires comparing proofs easily.
40//!
41//! This library uses a lifting mechanism for making it easier
42//! to produce proofs in classical logic and compare them to
43//! proofs in constructive logic.
44//!
45//! ### Design
46//!
47//! This library contains:
48//!
49//! - `Prop`: Propositions that might or might not be decidable (constructive logic)
50//! - `EProp`: Existential propositions (existential logic)
51//! - `DProp`: Decidable propositions (classical logic)
52//! - `LProp`: Like `Prop`, but with path semantics (path semantical constructive logic)
53//! - `ELProp`: Like `EProp`, but with path semantics (path semantical existential logic)
54//! - `DLProp`: Like `DProp`, but with path semantics (path semantical classical logic)
55//! - Automatic lifting of Excluded Middle of Non-Existence to existential propositions
56//! - Automatic lifting of Excluded Middle to decidable propositions
57//! - Double Negation for proofs of `Prop`
58//! - A model of Path Semantical Quality/Aquality in IPL (see "quality" module)
59//! - A model of Path Semantical Qubit in IPL (see "qubit" module)
60//! - A model of Path Semantical Con-Quality in IPL (see "con_qubit" module)
61//! - A model of Seshatic Queenity (see "queenity" module)
62//! - Formalization of the core axiom of Path Semantics
63//! - Exponential Propositions (HOOO) for tautological/paradoxical theorem proving
64//! - A model of S5 Modal Logic derived from HOOO EP
65//! - A model of Avatar Modal Logic derived from HOOO EP and Theory of Avatar Extensions
66//! - A model of Middle Exponential Logic using EL and HOOO EP
67//! - Tactics organized in modules by constructs (e.g. `and` or `imply`)
68//!
69//! ### Examples
70//!
71//! ```rust
72//! use prop::*;
73//!
74//! fn proof<A: Prop, B: Prop>(f: Imply<A, B>, a: A) -> B {
75//! imply::modus_ponens(f, a)
76//! }
77//! ```
78//!
79//! Notice that there is no `DProp` used here,
80//! which means that it is a constructive proof.
81//!
82//! ```rust
83//! use prop::*;
84//!
85//! fn proof<A: DProp, B: DProp>(f: Imply<Not<A>, Not<B>>) -> Imply<B, A> {
86//! imply::rev_modus_tollens(f)
87//! }
88//! ```
89//!
90//! Here, `DProp` is needed because `rev_modus_tollens` needs Excluded Middle.
91//! This limits the proof to decidable propositions.
92//!
93//! ### Path Semantics
94//!
95//! Path Semantics is an extremely expressive language for mathematical programming.
96//! It uses a single core axiom, which models semantics of symbols.
97//!
98//! Basically, mathematical languages contain a hidden symmetry due to use of symbols.
99//! Counter-intuitively, symbols are not "inherently" in logic.
100//!
101//! One way to put it, is that the symbols "themselves" encode laws of mathematics.
102//! The hidden symmetry can be exploited to prove semantics and sometimes
103//! improve performance of automated theorem provers.
104//!
105//! For more information, see the [Path Semantics Project](https://github.com/advancedresearch/path_semantics).
106
107use std::rc::Rc;
108
109use Either::*;
110
111pub mod and;
112#[cfg(feature = "avatar_extensions")]
113pub mod avatar_extensions;
114pub mod imply;
115pub mod eq;
116pub mod not;
117pub mod or;
118pub mod path_semantics;
119pub mod nat;
120pub mod quality;
121pub mod quality_traits;
122pub mod qubit;
123pub mod queenity;
124pub mod univalence;
125#[cfg(feature = "quantify")]
126pub mod quantify;
127pub mod existence;
128pub mod con_qubit;
129pub mod hooo;
130pub mod hooo_traits;
131pub mod hott;
132pub mod modal;
133pub mod ava_modal;
134pub mod mid;
135pub mod fun;
136pub mod fun_traits;
137pub mod sd;
138pub mod halt;
139
140/// Logical true.
141#[derive(Copy, Clone)]
142pub struct True;
143/// Logical false.
144#[derive(Copy, Clone)]
145pub enum False {}
146
147/// Sum type of left and right case.
148#[derive(Copy, Clone)]
149pub enum Either<T, U> {
150 /// Left case.
151 Left(T),
152 /// Right case.
153 Right(U),
154}
155
156/// Logical AND.
157pub type And<T, U> = (T, U);
158/// Double negation.
159pub type Dneg<T> = Imply<Not<Not<T>>, T>;
160/// Logical EQ.
161pub type Eq<T, U> = And<Imply<T, U>, Imply<U, T>>;
162/// Alternative to Logical EQ.
163pub type Iff<T, U> = Eq<T, U>;
164/// Logical IMPLY.
165pub type Imply<T, U> = Rc<dyn Fn(T) -> U>;
166/// Excluded middle.
167pub type ExcM<T> = Or<T, Not<T>>;
168/// Logical NOT.
169pub type Not<T> = Imply<T, False>;
170/// Logical OR.
171pub type Or<T, U> = Either<T, U>;
172
173/// A proposition that might be decidable or undecidable.
174pub trait Prop: 'static + Sized + Clone {
175 /// Get double negation rule from proof.
176 fn double_neg(self) -> Dneg<Self> {self.map_any()}
177 /// Maps anything into itself.
178 fn map_any<T>(self) -> Imply<T, Self> {Rc::new(move |_| self.clone())}
179 /// Double negated excluded middle.
180 fn nnexcm() -> Not<Not<ExcM<Self>>> {
181 Rc::new(move |nexcm| {
182 let nexcm2 = nexcm.clone();
183 let f: Not<Self> = Rc::new(move |a| nexcm2(Left(a)));
184 let g: Not<Not<Self>> = Rc::new(move |na| nexcm(Right(na)));
185 g(f)
186 })
187 }
188}
189impl<T: 'static + Sized + Clone> Prop for T {}
190
191/// Implemented by decidable types.
192pub trait Decidable: Prop {
193 /// Get excluded middle rule.
194 fn decide() -> ExcM<Self>;
195}
196
197impl Decidable for True {
198 fn decide() -> ExcM<True> {Left(True)}
199}
200impl Decidable for False {
201 fn decide() -> ExcM<False> {Right(Rc::new(move |x| x))}
202}
203impl<T, U> Decidable for And<T, U> where T: Decidable, U: Decidable {
204 fn decide() -> ExcM<Self> {
205 match (<T as Decidable>::decide(), <U as Decidable>::decide()) {
206 (Left(a), Left(b)) => Left((a, b)),
207 (_, Right(b)) => Right(Rc::new(move |(_, x)| b.clone()(x))),
208 (Right(a), _) => Right(Rc::new(move |(x, _)| a.clone()(x))),
209 }
210 }
211}
212impl<T, U> Decidable for Or<T, U> where T: Decidable, U: Decidable {
213 fn decide() -> ExcM<Self> {
214 match (<T as Decidable>::decide(), <U as Decidable>::decide()) {
215 (Left(a), _) => Left(Left(a)),
216 (_, Left(b)) => Left(Right(b)),
217 (Right(a), Right(b)) => Right(Rc::new(move |f| match f {
218 Left(x) => a.clone()(x),
219 Right(y) => b.clone()(y),
220 }))
221 }
222 }
223}
224impl<T, U> Decidable for Imply<T, U> where T: Decidable, U: Decidable {
225 fn decide() -> ExcM<Self> {
226 match (<T as Decidable>::decide(), <U as Decidable>::decide()) {
227 (_, Left(b)) => Left(b.map_any()),
228 (Left(a), Right(b)) =>
229 Right(Rc::new(move |f| b.clone()(f(a.clone())))),
230 (Right(a), _) => {
231 let g: Imply<Not<U>, Not<T>> = a.map_any();
232 Left(imply::rev_modus_tollens(g))
233 }
234 }
235 }
236}
237
238/// Shorthand for decidable proposition.
239pub trait DProp: Decidable {}
240impl<T: Decidable> DProp for T {}