prolog2/program/
clause.rs1use std::{ops::Deref, sync::Arc};
4
5use crate::heap::heap::Heap;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
9pub struct BitFlag64(u64);
10
11impl BitFlag64 {
12 pub fn set(&mut self, idx: usize) {
13 self.0 = self.0 | 1 << idx;
14 }
15
16 pub fn _unset(&mut self, idx: usize) {
17 self.0 = self.0 & !(1 << idx);
18 }
19
20 pub fn get(&self, idx: usize) -> bool {
21 self.0 & (1 << idx) != 0
22 }
23}
24
25#[derive(Debug, Clone, Eq, PartialEq)]
28pub struct Clause {
29 literals: Arc<[usize]>,
30 pub meta_vars: Option<BitFlag64>,
31 pub constrained_vars: BitFlag64,
32}
33
34impl Clause {
35 fn meta_vars_to_bit_flags(meta_vars: Vec<usize>) -> BitFlag64 {
36 let mut bit_flags = BitFlag64::default();
37 for meta_var in meta_vars {
38 if meta_var > 63 {
39 panic!("Cant have more than 64 variables in meta clause")
40 }
41 bit_flags.set(meta_var);
42 }
43 bit_flags
44 }
45
46 pub fn new(literals: Vec<usize>, meta_vars: Option<Vec<usize>>, constrained_vars: Option<Vec<usize>>) -> Self {
47 let meta_vars = meta_vars.map(Self::meta_vars_to_bit_flags);
48 let constrained_vars = match constrained_vars {
49 Some(cv) => Self::meta_vars_to_bit_flags(cv),
50 None => meta_vars.unwrap_or_default(),
51 };
52 let literals: Arc<[usize]> = literals.into();
53 Clause {
54 literals,
55 meta_vars,
56 constrained_vars,
57 }
58 }
59
60 pub fn head(&self) -> usize {
61 self[0]
62 }
63
64 pub fn body(&self) -> &[usize] {
65 &self[1..]
66 }
67
68 pub fn meta(&self) -> bool {
69 self.meta_vars.is_some()
70 }
71
72 pub fn meta_var(&self, arg_id: usize) -> Result<bool, &'static str> {
73 let meta_vars = self.meta_vars.ok_or("Clause is not a meta clause")?;
74 Ok(meta_vars.get(arg_id))
75 }
76
77 pub fn constrained_var(&self, arg_id: usize) -> bool {
78 self.constrained_vars.get(arg_id)
79 }
80
81 pub fn to_string(&self, heap: &impl Heap) -> String {
82 let mut buffer = format!("{}:-", heap.term_string(self.head()));
83 for body_literal in self.body() {
84 buffer += &heap.term_string(*body_literal);
85 buffer += ","
86 }
87 buffer.pop();
88 buffer += ".";
89 buffer
90 }
91}
92
93impl Deref for Clause {
94 type Target = [usize];
95
96 fn deref(&self) -> &[usize] {
97 &self.literals
98 }
99}