1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
//! Path Semantical Quality
//!
//! This implementation uses a 2-avatar of equality
//! to model [quality](https://github.com/advancedresearch/path_semantics/blob/master/papers-wip2/path-semantical-quality.pdf)
//! within IPL, by exploiting the property `(a == b) => ( (a ~~ b) ⋁ ¬¬(a ~~ b) )`.
//!
//! IPL does not have symbolic distinction,
//! so equality `a == b` can not be lifted properly into `a ~~ b`.
//! However, since quality is not decidable within IPL,
//! one can not prove `a ~~ b` from `¬¬(a ~~ b)`.
//! This means that the 2-avatar can hide reflexivity,
//! by lifting `a == b` to `(a ~~ b) ⋁ ¬¬(a ~~ b)`.
//!
//! Notice that this implementation does not support reasoning
//! about [Seshatism](https://github.com/advancedresearch/path_semantics/blob/master/papers-wip2/seshatism.pdf),
//! because `¬(a ~~ a)` (Seshatism) is absurd in this model (it proves anything).
//! Proper Seshatism requires quality to use symbolic distinction instead of the trick above.
//! For a different implementation of quality, see [PSI in Avalog](https://github.com/advancedresearch/avalog/blob/master/source/psi.txt).
//!
//! Interpreted as an [Avatar Graph](https://advancedresearch.github.io/avatar-extensions/summary.html#avatar-graphs),
//! the core is `a == b` and there are two 1-avatars:
//!
//! - `(a ~~ b)`
//! - `¬¬(a ~~ b)`
//!
//! The 2-avatar integrates `(a ~~ b)` and `¬¬(a ~~ b)` using `⋁`.
use crate::*;
pub use commute as symmetry;
/// Quality between `A` and `B` (`A ~~ B`).
#[derive(Clone)]
pub struct Q<A, B>(Eq<A, B>);
/// Symmetry `(a ~~ b) => (b ~~ a)`.
pub fn commute<A: Prop, B: Prop>(Q((ab, ba)): Q<A, B>) -> Q<B, A> {
Q((ba, ab))
}
/// Transitivity `(a ~~ b) ⋀ (b ~~ c) => (a ~~ c)`.
pub fn transitivity<A: Prop, B: Prop, C: Prop>(
Q((ab, ba)): Q<A, B>,
Q((bc, cb)): Q<B, C>
) -> Q<A, C> {
Q((Rc::new(move |a| bc(ab(a))), Rc::new(move |c| ba(cb(c)))))
}
/// Equality lift `(a == b) => ( (a ~~ b) ⋁ ¬¬(a ~~ b) )`.
pub fn eq_lift<A: Prop, B: Prop>(eq: Eq<A, B>) -> Or<Q<A, B>, Not<Not<Q<A, B>>>> {
Left(Q(eq))
}
/// Converts to equality `(a ~~ b) => (a == b)`.
pub fn to_eq<A: Prop, B: Prop>(Q(eq): Q<A, B>) -> Eq<A, B> {
eq
}
/// `(a ~~ b) => (a ~~ a)`.
pub fn self_quality_left<A: Prop, B: Prop>(q_ab: Q<A, B>) -> Q<A, A> {
let q_ba = symmetry(q_ab.clone());
transitivity(q_ab, q_ba)
}
/// `(a ~~ b) => (b ~~ b)`.
pub fn self_quality_right<A: Prop, B: Prop>(q_ab: Q<A, B>) -> Q<B, B> {
let q_ba = symmetry(q_ab.clone());
transitivity(q_ba, q_ab)
}
/// Mirror `¬¬(a ~~ a)`.
pub fn mirror<A: Prop>() -> Not<Not<Q<A, A>>> {
match eq_lift(eq::refl()) {
Left(q_aa) => not::double(q_aa),
Right(nn_q_aa) => nn_q_aa,
}
}
/// Excluded middle implies reflexivity.
pub fn excm_refl<A: Prop>(exc: ExcM<Q<A, A>>) -> Q<A, A> {
match exc {
Left(q) => q,
Right(n_q) => imply::absurd()(mirror()(n_q)),
}
}
/// `¬(a ~~ b) ⋀ (a == b) => c`.
pub fn absurd<A: Prop, B: Prop, C: Prop>(
n_q: Not<Q<A, B>>,
eq: Eq<A, B>,
) -> C {
match eq_lift(eq) {
Left(q) => not::absurd(n_q, q),
Right(nn_q) => not::absurd(nn_q, n_q),
}
}
/// `¬(a ~~ a) => b`.
pub fn sesh_absurd<A: Prop, B: Prop>(f: Not<Q<A, A>>) -> B {
not::absurd(mirror(), f)
}