use crate::engine::Paradigm;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum SemanticClass {
Conjunction, Disjunction, Negation, Implication, Biconditional, ExclusiveOr, Verum, Falsum,
Necessity, Possibility,
Knows, Believes, CommonKnowledge, DistributedKnowledge,
Obligatory, Permitted, Forbidden, Waived,
Globally, Finally, Next, Until, Release, WeakUntil,
MembershipDegree, FuzzyAnd, FuzzyOr, Probability,
BothTrueAndFalse, NeitherTrueNorFalse,
Universal, Existential, UniqueExistential,
ElementOf, NotElementOf, Subset, StrictSubset, Union, Intersection, EmptySet,
Equals, NotEquals, LessThan, LessOrEqual, GreaterThan, GreaterOrEqual,
Turnstile, DoubleTurnstile, Therefore, Because,
Identifier,
NumericLiteral,
StringLiteral,
BooleanLiteral,
TimeLiteral,
}
impl SemanticClass {
pub fn paradigms(self) -> &'static [Paradigm] {
match self {
SemanticClass::Conjunction
| SemanticClass::Disjunction
| SemanticClass::Negation
| SemanticClass::Implication
| SemanticClass::Biconditional
| SemanticClass::ExclusiveOr
| SemanticClass::Verum
| SemanticClass::Falsum => &[Paradigm::Boolean],
SemanticClass::Necessity | SemanticClass::Possibility => {
&[Paradigm::Modal, Paradigm::Epistemic]
}
SemanticClass::Knows
| SemanticClass::Believes
| SemanticClass::CommonKnowledge
| SemanticClass::DistributedKnowledge => &[Paradigm::Epistemic],
SemanticClass::Obligatory
| SemanticClass::Permitted
| SemanticClass::Forbidden
| SemanticClass::Waived => &[Paradigm::Deontic],
SemanticClass::Globally
| SemanticClass::Finally
| SemanticClass::Next
| SemanticClass::Until
| SemanticClass::Release
| SemanticClass::WeakUntil => &[Paradigm::Temporal],
SemanticClass::MembershipDegree | SemanticClass::FuzzyAnd | SemanticClass::FuzzyOr => {
&[Paradigm::Fuzzy]
}
SemanticClass::Probability => &[Paradigm::Probabilistic],
SemanticClass::BothTrueAndFalse | SemanticClass::NeitherTrueNorFalse => {
&[Paradigm::Paraconsistent]
}
SemanticClass::Universal
| SemanticClass::Existential
| SemanticClass::UniqueExistential => &[Paradigm::Boolean, Paradigm::Modal],
_ => &[Paradigm::Boolean],
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct Symbol {
pub codepoint: u32,
pub keyword: Option<&'static str>,
pub name: &'static str,
pub class: SemanticClass,
}
pub struct UnicodeSemanticDictionary;
impl UnicodeSemanticDictionary {
pub const ENTRIES: &'static [Symbol] = &[
Symbol {
codepoint: 0x2227,
keyword: Some("and"),
name: "Conjunction",
class: SemanticClass::Conjunction,
},
Symbol {
codepoint: 0x2228,
keyword: Some("or"),
name: "Disjunction",
class: SemanticClass::Disjunction,
},
Symbol {
codepoint: 0x00AC,
keyword: Some("not"),
name: "Negation",
class: SemanticClass::Negation,
},
Symbol {
codepoint: 0x2192,
keyword: Some("implies"),
name: "Implication",
class: SemanticClass::Implication,
},
Symbol {
codepoint: 0x2194,
keyword: Some("iff"),
name: "Biconditional",
class: SemanticClass::Biconditional,
},
Symbol {
codepoint: 0x2295,
keyword: Some("xor"),
name: "ExclusiveOr",
class: SemanticClass::ExclusiveOr,
},
Symbol {
codepoint: 0x22A4,
keyword: Some("true"),
name: "Verum",
class: SemanticClass::Verum,
},
Symbol {
codepoint: 0x22A5,
keyword: Some("false"),
name: "Falsum",
class: SemanticClass::Falsum,
},
Symbol {
codepoint: 0x25A1,
keyword: Some("necessarily"),
name: "Necessity",
class: SemanticClass::Necessity,
},
Symbol {
codepoint: 0x25C7,
keyword: Some("possibly"),
name: "Possibility",
class: SemanticClass::Possibility,
},
Symbol {
codepoint: 0x004B,
keyword: Some("knows"),
name: "Knows",
class: SemanticClass::Knows,
},
Symbol {
codepoint: 0x0042,
keyword: Some("believes"),
name: "Believes",
class: SemanticClass::Believes,
},
Symbol {
codepoint: 0x0043,
keyword: Some("common_knowledge"),
name: "CommonKnowledge",
class: SemanticClass::CommonKnowledge,
},
Symbol {
codepoint: 0x0044,
keyword: Some("distributed_knowledge"),
name: "DistributedKnowledge",
class: SemanticClass::DistributedKnowledge,
},
Symbol {
codepoint: 0x004F,
keyword: Some("must"),
name: "Obligatory",
class: SemanticClass::Obligatory,
},
Symbol {
codepoint: 0x0050,
keyword: Some("may"),
name: "Permitted",
class: SemanticClass::Permitted,
},
Symbol {
codepoint: 0x0046,
keyword: Some("must_not"),
name: "Forbidden",
class: SemanticClass::Forbidden,
},
Symbol {
codepoint: 0x0000,
keyword: Some("ought"),
name: "Obligatory",
class: SemanticClass::Obligatory,
},
Symbol {
codepoint: 0x0000,
keyword: Some("should"),
name: "Obligatory",
class: SemanticClass::Obligatory,
},
Symbol {
codepoint: 0x0000,
keyword: Some("prohibited"),
name: "Forbidden",
class: SemanticClass::Forbidden,
},
Symbol {
codepoint: 0x0000,
keyword: Some("permitted"),
name: "Permitted",
class: SemanticClass::Permitted,
},
Symbol {
codepoint: 0x0000,
keyword: Some("allowed"),
name: "Permitted",
class: SemanticClass::Permitted,
},
Symbol {
codepoint: 0x0000,
keyword: Some("forbidden"),
name: "Forbidden",
class: SemanticClass::Forbidden,
},
Symbol {
codepoint: 0x0000,
keyword: Some("waived"),
name: "Waived",
class: SemanticClass::Waived,
},
Symbol {
codepoint: 0x0047,
keyword: Some("always"),
name: "Globally",
class: SemanticClass::Globally,
},
Symbol {
codepoint: 0x0046,
keyword: Some("eventually"),
name: "Finally",
class: SemanticClass::Finally,
},
Symbol {
codepoint: 0x0058,
keyword: Some("next"),
name: "Next",
class: SemanticClass::Next,
},
Symbol {
codepoint: 0x0055,
keyword: Some("until"),
name: "Until",
class: SemanticClass::Until,
},
Symbol {
codepoint: 0x0052,
keyword: Some("release"),
name: "Release",
class: SemanticClass::Release,
},
Symbol {
codepoint: 0x0000,
keyword: Some("never"),
name: "Globally(¬)",
class: SemanticClass::Globally,
},
Symbol {
codepoint: 0x0000,
keyword: Some("within"),
name: "Finally",
class: SemanticClass::Finally,
},
Symbol {
codepoint: 0x0000,
keyword: Some("before"),
name: "Until",
class: SemanticClass::Until,
},
Symbol {
codepoint: 0x0000,
keyword: Some("after"),
name: "Finally",
class: SemanticClass::Finally,
},
Symbol {
codepoint: 0x0000,
keyword: Some("deadline"),
name: "Until",
class: SemanticClass::Until,
},
Symbol {
codepoint: 0x03BC,
keyword: Some("mu"),
name: "MembershipDegree",
class: SemanticClass::MembershipDegree,
},
Symbol {
codepoint: 0x2293,
keyword: Some("fuzzy_and"),
name: "FuzzyAnd",
class: SemanticClass::FuzzyAnd,
},
Symbol {
codepoint: 0x2294,
keyword: Some("fuzzy_or"),
name: "FuzzyOr",
class: SemanticClass::FuzzyOr,
},
Symbol {
codepoint: 0x0000,
keyword: Some("probability"),
name: "Probability",
class: SemanticClass::Probability,
},
Symbol {
codepoint: 0x0000,
keyword: Some("likely"),
name: "Probability",
class: SemanticClass::Probability,
},
Symbol {
codepoint: 0x0000,
keyword: Some("unlikely"),
name: "Probability",
class: SemanticClass::Probability,
},
Symbol {
codepoint: 0x2200,
keyword: Some("forall"),
name: "Universal",
class: SemanticClass::Universal,
},
Symbol {
codepoint: 0x2203,
keyword: Some("exists"),
name: "Existential",
class: SemanticClass::Existential,
},
Symbol {
codepoint: 0x2204,
keyword: Some("exists_unique"),
name: "UniqueExistential",
class: SemanticClass::UniqueExistential,
},
Symbol {
codepoint: 0x2208,
keyword: Some("in"),
name: "ElementOf",
class: SemanticClass::ElementOf,
},
Symbol {
codepoint: 0x2209,
keyword: Some("not_in"),
name: "NotElementOf",
class: SemanticClass::NotElementOf,
},
Symbol {
codepoint: 0x2286,
keyword: Some("subset"),
name: "Subset",
class: SemanticClass::Subset,
},
Symbol {
codepoint: 0x2282,
keyword: Some("strict_subset"),
name: "StrictSubset",
class: SemanticClass::StrictSubset,
},
Symbol {
codepoint: 0x222A,
keyword: Some("union"),
name: "Union",
class: SemanticClass::Union,
},
Symbol {
codepoint: 0x2229,
keyword: Some("intersect"),
name: "Intersection",
class: SemanticClass::Intersection,
},
Symbol {
codepoint: 0x2205,
keyword: Some("empty"),
name: "EmptySet",
class: SemanticClass::EmptySet,
},
Symbol {
codepoint: 0x003D,
keyword: Some("eq"),
name: "Equals",
class: SemanticClass::Equals,
},
Symbol {
codepoint: 0x2260,
keyword: Some("neq"),
name: "NotEquals",
class: SemanticClass::NotEquals,
},
Symbol {
codepoint: 0x003C,
keyword: Some("lt"),
name: "LessThan",
class: SemanticClass::LessThan,
},
Symbol {
codepoint: 0x2264,
keyword: Some("lte"),
name: "LessOrEqual",
class: SemanticClass::LessOrEqual,
},
Symbol {
codepoint: 0x003E,
keyword: Some("gt"),
name: "GreaterThan",
class: SemanticClass::GreaterThan,
},
Symbol {
codepoint: 0x2265,
keyword: Some("gte"),
name: "GreaterOrEqual",
class: SemanticClass::GreaterOrEqual,
},
Symbol {
codepoint: 0x22A2,
keyword: Some("proves"),
name: "Turnstile",
class: SemanticClass::Turnstile,
},
Symbol {
codepoint: 0x22A8,
keyword: Some("models"),
name: "DoubleTurnstile",
class: SemanticClass::DoubleTurnstile,
},
Symbol {
codepoint: 0x2234,
keyword: Some("therefore"),
name: "Therefore",
class: SemanticClass::Therefore,
},
Symbol {
codepoint: 0x2235,
keyword: Some("because"),
name: "Because",
class: SemanticClass::Because,
},
];
pub fn lookup_codepoint(cp: u32) -> Option<&'static Symbol> {
Self::ENTRIES
.iter()
.find(|s| s.codepoint == cp && s.codepoint != 0)
}
pub fn lookup_keyword(kw: &str) -> Option<&'static Symbol> {
let mut buf = [0u8; 64];
let kw_bytes = kw.as_bytes();
let len = kw_bytes.len().min(64);
for (i, &b) in kw_bytes[..len].iter().enumerate() {
buf[i] = b.to_ascii_lowercase();
}
let lower = core::str::from_utf8(&buf[..len]).ok()?;
Self::ENTRIES.iter().find(|s| s.keyword == Some(lower))
}
pub fn detect_paradigms(classes: &[SemanticClass]) -> ParadigmSet {
let mut set = ParadigmSet::empty();
for cls in classes {
for &p in cls.paradigms() {
set.insert(p);
}
}
set.insert(Paradigm::Boolean);
set
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ParadigmSet(u16);
impl ParadigmSet {
pub const fn empty() -> Self {
Self(0)
}
pub fn insert(&mut self, p: Paradigm) {
self.0 |= 1 << (p as u8);
}
pub fn contains(&self, p: Paradigm) -> bool {
self.0 & (1 << (p as u8)) != 0
}
pub fn is_empty(&self) -> bool {
self.0 == 0
}
pub fn iter(&self) -> impl Iterator<Item = Paradigm> + '_ {
Paradigm::ALL.iter().copied().filter(|&p| self.contains(p))
}
}