datalog_structural_model/ir/
atom.rs1use std::collections::BTreeSet;
4use std::fmt;
5
6use super::symbols::{PredicateSymbol, VariableSymbol};
7use super::term::Term;
8
9#[derive(Clone, Debug, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
11#[serde(deny_unknown_fields)]
12pub struct Atom {
13 pub predicate: PredicateSymbol,
15 pub terms: Vec<Term>,
17}
18
19impl Atom {
20 #[must_use]
22 pub fn arity(&self) -> usize {
23 self.terms.len()
24 }
25
26 #[must_use]
30 pub(super) fn variables(&self) -> BTreeSet<VariableSymbol> {
31 let mut acc = BTreeSet::new();
32 self.collect_variables(&mut acc);
33 acc
34 }
35
36 fn collect_variables(&self, acc: &mut BTreeSet<VariableSymbol>) {
37 for term in &self.terms {
38 term.collect_variables(acc);
39 }
40 }
41
42 #[must_use]
47 pub(super) fn nesting_depth(&self) -> usize {
48 self.terms
49 .iter()
50 .map(Term::nesting_depth)
51 .max()
52 .unwrap_or(0)
53 }
54}
55
56impl fmt::Display for Atom {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 write!(f, "{}(", self.predicate.as_str())?;
62 for (idx, term) in self.terms.iter().enumerate() {
63 if idx > 0 {
64 write!(f, ", ")?;
65 }
66 write!(f, "{term}")?;
67 }
68 write!(f, ")")
69 }
70}