use alloc::vec::Vec;
use crate::ast::{
AstId, AstKind, DeclKind, FamilyId, NULL_DECL_KIND, NULL_FAMILY_ID, Parameter, SortSize,
};
use crate::util::symbol::Symbol;
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct DeclInfo {
pub family_id: FamilyId,
pub decl_kind: DeclKind,
pub parameters: Vec<Parameter>,
}
impl DeclInfo {
pub fn null() -> DeclInfo {
DeclInfo {
family_id: NULL_FAMILY_ID,
decl_kind: NULL_DECL_KIND,
parameters: Vec::new(),
}
}
pub fn new(family_id: FamilyId, decl_kind: DeclKind, parameters: Vec<Parameter>) -> DeclInfo {
DeclInfo {
family_id,
decl_kind,
parameters,
}
}
pub fn is_null(&self) -> bool {
self.family_id == NULL_FAMILY_ID && self.parameters.is_empty()
}
pub fn is_decl_of(&self, fid: FamilyId, k: DeclKind) -> bool {
self.family_id == fid && self.decl_kind == k
}
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct SortData {
pub name: Symbol,
pub info: DeclInfo,
pub num_elements: SortSize,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
pub struct FuncDeclFlags {
pub left_assoc: bool,
pub right_assoc: bool,
pub flat_associative: bool,
pub commutative: bool,
pub chainable: bool,
pub pairwise: bool,
pub injective: bool,
pub idempotent: bool,
pub skolem: bool,
pub polymorphic: bool,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct FuncDeclData {
pub name: Symbol,
pub info: DeclInfo,
pub flags: FuncDeclFlags,
pub domain: Vec<AstId>,
pub range: AstId,
}
impl FuncDeclData {
#[inline]
pub fn arity(&self) -> usize {
self.domain.len()
}
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct AppData {
pub decl: AstId,
pub args: Vec<AstId>,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub struct VarData {
pub index: u32,
pub sort: AstId,
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum QuantifierKind {
Forall,
Exists,
Lambda,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct QuantifierData {
pub kind: QuantifierKind,
pub var_sorts: Vec<AstId>,
pub var_names: Vec<Symbol>,
pub body: AstId,
pub patterns: Vec<AstId>,
pub weight: i32,
pub sort: AstId,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum AstNode {
Sort(SortData),
FuncDecl(FuncDeclData),
App(AppData),
Var(VarData),
Quantifier(QuantifierData),
}
impl AstNode {
pub const fn kind(&self) -> AstKind {
match self {
AstNode::App(_) => AstKind::App,
AstNode::Var(_) => AstKind::Var,
AstNode::Sort(_) => AstKind::Sort,
AstNode::FuncDecl(_) => AstKind::FuncDecl,
AstNode::Quantifier(_) => AstKind::Quantifier,
}
}
}