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