use super::common::*;
#[derive(Debug, Clone, PartialEq)]
pub enum THFStatement<'a> {
Logical(THFFormula<'a>),
Typing(THFTyping<'a>),
Subtype(THFType<'a>, THFType<'a>),
Sequent(Vec<THFFormula<'a>>, Vec<THFFormula<'a>>),
Logic(LogicSpecification<'a>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct THFTyping<'a> {
pub symbol: THFTypedSymbol<'a>,
pub typ: THFType<'a>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum THFTypedSymbol<'a> {
Atom(AtomicWord<'a>),
Defined(DefinedWord<'a>),
System(SystemWord<'a>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum THFFormula<'a> {
Atomic(THFAtomicFormula<'a>),
Variable(&'a str),
Negation(Box<THFFormula<'a>>),
Quantified {
quantifier: THFQuantifier,
variables: Vec<THFVariable<'a>>,
formula: Box<THFFormula<'a>>,
},
Binary {
left: Box<THFFormula<'a>>,
connective: THFBinaryConnective,
right: Box<THFFormula<'a>>,
},
Application(Box<THFFormula<'a>>, Box<THFFormula<'a>>),
Lambda {
variables: Vec<THFVariable<'a>>,
body: Box<THFFormula<'a>>,
},
Equality(Box<THFFormula<'a>>, Box<THFFormula<'a>>),
Inequality(Box<THFFormula<'a>>, Box<THFFormula<'a>>),
Parens(Box<THFFormula<'a>>),
Typed(Box<THFFormula<'a>>, THFType<'a>),
Conditional {
condition: Box<THFFormula<'a>>,
then_branch: Box<THFFormula<'a>>,
else_branch: Box<THFFormula<'a>>,
},
Let {
definitions: Vec<THFLetDef<'a>>,
body: Box<THFFormula<'a>>,
},
Tuple(Vec<THFFormula<'a>>),
Number(Number<'a>),
DistinctObject(&'a str),
NonClassical {
operator: NonClassicalOperator<'a>,
formula: Option<Box<THFFormula<'a>>>,
},
ConnectiveTerm(THFBinaryConnective),
UnaryConnectiveTerm,
QuantifierTerm(THFQuantifier),
EqualityTerm,
TypeAsFormula(THFType<'a>),
}
impl<'a> THFFormula<'a> {
pub fn app(f: THFFormula<'a>, g: THFFormula<'a>) -> Self {
THFFormula::Application(Box::new(f), Box::new(g))
}
pub fn lambda(variables: Vec<THFVariable<'a>>, body: THFFormula<'a>) -> Self {
THFFormula::Lambda {
variables,
body: Box::new(body),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct THFVariable<'a> {
pub name: &'a str,
pub typ: Option<THFType<'a>>,
}
impl<'a> THFVariable<'a> {
pub fn new(name: &'a str) -> Self {
THFVariable { name, typ: None }
}
pub fn typed(name: &'a str, typ: THFType<'a>) -> Self {
THFVariable {
name,
typ: Some(typ),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum THFQuantifier {
Forall,
Exists,
Lambda,
Choice,
Description,
ForallType,
ExistsType,
}
impl THFQuantifier {
pub fn as_str(&self) -> &'static str {
match self {
THFQuantifier::Forall => "!",
THFQuantifier::Exists => "?",
THFQuantifier::Lambda => "^",
THFQuantifier::Choice => "@+",
THFQuantifier::Description => "@-",
THFQuantifier::ForallType => "!>",
THFQuantifier::ExistsType => "?*",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum THFBinaryConnective {
Iff,
Impl,
RevImpl,
Xor,
Nor,
Nand,
Or,
And,
Arrow,
Product,
Sum,
Assign,
MetaIdentity,
}
impl THFBinaryConnective {
pub fn as_str(&self) -> &'static str {
match self {
THFBinaryConnective::Iff => "<=>",
THFBinaryConnective::Impl => "=>",
THFBinaryConnective::RevImpl => "<=",
THFBinaryConnective::Xor => "<~>",
THFBinaryConnective::Nor => "~|",
THFBinaryConnective::Nand => "~&",
THFBinaryConnective::Or => "|",
THFBinaryConnective::And => "&",
THFBinaryConnective::Arrow => ">",
THFBinaryConnective::Product => "*",
THFBinaryConnective::Sum => "+",
THFBinaryConnective::Assign => ":=",
THFBinaryConnective::MetaIdentity => "==",
}
}
pub fn from_common(c: BinaryConnective) -> Self {
match c {
BinaryConnective::Iff => THFBinaryConnective::Iff,
BinaryConnective::Impl => THFBinaryConnective::Impl,
BinaryConnective::RevImpl => THFBinaryConnective::RevImpl,
BinaryConnective::Xor => THFBinaryConnective::Xor,
BinaryConnective::Nor => THFBinaryConnective::Nor,
BinaryConnective::Nand => THFBinaryConnective::Nand,
BinaryConnective::Or => THFBinaryConnective::Or,
BinaryConnective::And => THFBinaryConnective::And,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum THFAtomicFormula<'a> {
Plain(AtomicWord<'a>, Vec<THFFormula<'a>>),
Defined(DefinedWord<'a>, Vec<THFFormula<'a>>),
System(SystemWord<'a>, Vec<THFFormula<'a>>),
True,
False,
}
#[derive(Debug, Clone, PartialEq)]
pub struct THFLetDef<'a> {
pub symbol: AtomicWord<'a>,
pub type_args: Vec<&'a str>,
pub params: Vec<THFVariable<'a>>,
pub definition: THFFormula<'a>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum THFType<'a> {
Atomic(AtomicWord<'a>),
Defined(THFDefinedType),
Variable(&'a str),
Arrow(Box<THFType<'a>>, Box<THFType<'a>>),
Product(Box<THFType<'a>>, Box<THFType<'a>>),
Sum(Box<THFType<'a>>, Box<THFType<'a>>),
Application(Box<THFType<'a>>, Vec<THFType<'a>>),
Tuple(Vec<THFType<'a>>),
Quantified {
quantifier: THFQuantifier,
variables: Vec<&'a str>,
typ: Box<THFType<'a>>,
},
DependentQuantified {
quantifier: THFQuantifier,
variables: Vec<THFVariable<'a>>,
typ: Box<THFType<'a>>,
},
Parens(Box<THFType<'a>>),
Mapping(Vec<THFType<'a>>, Box<THFType<'a>>),
}
impl<'a> THFType<'a> {
pub fn individual() -> Self {
THFType::Defined(THFDefinedType::I)
}
pub fn boolean() -> Self {
THFType::Defined(THFDefinedType::O)
}
pub fn ttype() -> Self {
THFType::Defined(THFDefinedType::TType)
}
pub fn arrow(from: THFType<'a>, to: THFType<'a>) -> Self {
THFType::Arrow(Box::new(from), Box::new(to))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum THFDefinedType {
I,
O,
Int,
Rat,
Real,
TType,
}
impl THFDefinedType {
pub fn as_str(&self) -> &'static str {
match self {
THFDefinedType::I => "$i",
THFDefinedType::O => "$o",
THFDefinedType::Int => "$int",
THFDefinedType::Rat => "$rat",
THFDefinedType::Real => "$real",
THFDefinedType::TType => "$tType",
}
}
pub fn parse(s: &str) -> Option<Self> {
match s {
"$i" | "i" => Some(THFDefinedType::I),
"$o" | "o" => Some(THFDefinedType::O),
"$int" | "int" => Some(THFDefinedType::Int),
"$rat" | "rat" => Some(THFDefinedType::Rat),
"$real" | "real" => Some(THFDefinedType::Real),
"$tType" | "tType" => Some(THFDefinedType::TType),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum NonClassicalOperator<'a> {
Box,
Diamond,
Always,
Eventually,
Knows,
Believes,
ShortBox(Option<&'a str>),
ShortDiamond(Option<&'a str>),
Custom {
name: &'a str,
index: Option<&'a str>,
},
}
impl<'a> NonClassicalOperator<'a> {
pub fn as_str(&self) -> &'static str {
match self {
NonClassicalOperator::Box => "{#box}",
NonClassicalOperator::Diamond => "{#dia}",
NonClassicalOperator::Always => "{#always}",
NonClassicalOperator::Eventually => "{#eventually}",
NonClassicalOperator::Knows => "{#knows}",
NonClassicalOperator::Believes => "{#believes}",
NonClassicalOperator::ShortBox(_) => "[.]",
NonClassicalOperator::ShortDiamond(_) => "<.>",
NonClassicalOperator::Custom { .. } => "{#custom}",
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct LogicSpecification<'a> {
pub logic_family: &'a str,
pub properties: Vec<LogicProperty<'a>>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum LogicProperty<'a> {
KeyValue { key: &'a str, value: LogicValue<'a> },
KeyList {
key: &'a str,
values: Vec<LogicProperty<'a>>,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum LogicValue<'a> {
Atom(&'a str),
String(&'a str),
List(Vec<LogicValue<'a>>),
Property {
name: &'a str,
value: Box<LogicValue<'a>>,
},
}