datalog_structural_model/
requirements.rs1use crate::ir::walk::Visitor;
3use crate::{BindExpr, BuiltinFilter, DatalogCapabilities, DatalogFeature, Literal, Program, Term};
4#[derive(Default)]
5struct Requirements(DatalogCapabilities);
6impl Visitor for Requirements {
7 fn term(&mut self, term: &Term) {
8 match term {
9 Term::Variable(_) | Term::Constant(_) => {}
10 Term::TripleTerm(_) => self.0.insert(DatalogFeature::TripleTerms),
11 Term::Skolem { .. } => self.0.insert(DatalogFeature::SkolemGeneration),
12 }
13 }
14 fn binding(&mut self, expr: &BindExpr) {
15 self.0.insert(DatalogFeature::Binding(expr.kind()));
16 }
17 fn filter(&mut self, expr: &BuiltinFilter) {
18 self.0.insert(DatalogFeature::Filter(expr.kind()));
19 }
20 fn literal(&mut self, literal: &Literal) {
21 match literal {
22 Literal::Negative(_) => self.0.insert(DatalogFeature::StratifiedNegation),
23 Literal::Aggregate(aggregate) => self
24 .0
25 .insert(DatalogFeature::Aggregate(aggregate.aggregator)),
26 Literal::Positive(_) | Literal::Filter(_) | Literal::Bind { .. } => {}
27 }
28 }
29}
30impl Program {
31 #[must_use]
34 pub fn required_capabilities(&self) -> DatalogCapabilities {
35 let mut requirements = Requirements::default();
36 for rule in &self.rules {
37 rule.walk(&mut requirements);
38 }
39 requirements.0
40 }
41}