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}