Skip to main content

prolog2/predicate_modules/
mod.rs

1/// Built-in maths predicates (`is/2`).
2pub mod maths;
3/// Built-in meta-predicates (`not/1`).
4pub mod meta_predicates;
5
6use std::sync::Arc;
7
8use crate::{
9    heap::{query_heap::QueryHeap, symbol_db::SymbolDB},
10    program::{hypothesis::Hypothesis, predicate_table::PredicateTable},
11    Config,
12};
13
14/// Return type for predicate functions.
15///
16/// A predicate either succeeds ([`PredReturn::True`]), fails ([`PredReturn::False`]),
17/// or succeeds with variable bindings ([`PredReturn::Binding`]).
18pub enum PredReturn {
19    True,
20    False,
21    /// Success with a list of `(source_addr, target_addr)` bindings to apply on the heap.
22    Binding(Vec<(usize, usize)>),
23}
24
25impl PredReturn {
26    /// Convenience: convert a bool into [`PredReturn::True`] or [`PredReturn::False`].
27    pub fn bool(value: bool) -> PredReturn {
28        if value {
29            PredReturn::True
30        } else {
31            PredReturn::False
32        }
33    }
34}
35
36/// Signature for a predicate function.
37///
38/// Arguments:
39/// - `&mut QueryHeap` — the current proof's working heap
40/// - `&mut Hypothesis` — the current learned hypothesis (may be extended)
41/// - `usize` — heap address of the goal term being resolved
42/// - `Arc<PredicateTable>` — the program's predicate table
43/// - `Config` — engine configuration
44pub type PredicateFunction = fn(
45    &mut QueryHeap,
46    &mut Hypothesis,
47    usize,
48    Arc<PredicateTable>,
49    Config,
50) -> PredReturn;
51
52/// A predicate module: a static slice of `(name, arity, function)` entries.
53///
54/// # Example
55///
56/// ```
57/// use prolog2::predicate_modules::{PredicateModule, PredReturn};
58///
59/// static MY_MODULE: PredicateModule = &[
60///     ("always_true", 0, |_heap, _hyp, _goal, _pt, _cfg| PredReturn::True),
61/// ];
62/// ```
63pub type PredicateModule = &'static [(&'static str, usize, PredicateFunction)];
64
65/// Register all entries from a predicate module into the predicate table.
66pub fn load_predicate_module(
67    predicate_table: &mut PredicateTable,
68    predicate_module: &PredicateModule,
69) {
70    for (symbol, arity, pred_fn) in predicate_module.iter() {
71        let _ = predicate_table.insert_predicate_function(
72            (SymbolDB::set_const((*symbol).to_string()), *arity),
73            *pred_fn,
74        );
75    }
76}
77
78/// Built-in maths predicates: `is/2` for arithmetic evaluation.
79pub static MATHS: PredicateModule = &[
80    ("is", 2, maths::is_pred),
81];
82
83/// Built-in meta-predicates: `not/1` (negation as failure).
84pub static META_PREDICATES: PredicateModule = &[("not", 1, meta_predicates::not)];
85
86/// Load all built-in predicate modules into the predicate table.
87pub fn load_all_modules(predicate_table: &mut PredicateTable) {
88    load_predicate_module(predicate_table, &MATHS);
89    load_predicate_module(predicate_table, &META_PREDICATES);
90}