materialized_view/builders/
goal.rs1use std::hash::Hash;
2use byteorder::ByteOrder;
3use crate::interning::hash::reproducible_hash_one;
4use crate::rewriting::atom::{EncodedFact, EncodedGoal};
5use crate::rewriting::rewrite::get_ith_term;
6
7#[allow(dead_code)]
8pub const ANY_VALUE: Option<()> = None;
9
10type GoalIR = [u64; 3];
11
12pub struct Goal { pub(crate) goal_ir: GoalIR }
13
14impl<T> From<(Option<T>,)> for Goal where T: Hash {
15 fn from(value: (Option<T>,)) -> Self {
16 let first = if value.0.is_none() { 0 } else { reproducible_hash_one(&value.0.unwrap()) };
17
18 return Self { goal_ir: [first, 0, 0] }
19 }
20}
21
22impl<T, R> From<(Option<T>, Option<R>)> for Goal where T: Hash, R: Hash {
23 fn from(value: (Option<T>, Option<R>)) -> Self {
24 let first = if value.0.is_none() { 0 } else { reproducible_hash_one(&value.0.unwrap()) };
25 let second = if value.1.is_none() { 0 } else { reproducible_hash_one(&value.1.unwrap()) };
26
27 return Self { goal_ir: [first, second, 0] }
28 }
29}
30
31impl<T, R, S> From<(Option<T>, Option<R>, Option<S>)> for Goal where T: Hash, R: Hash, S: Hash {
32 fn from(value: (Option<T>, Option<R>, Option<S>)) -> Self {
33 let first = if value.0.is_none() { 0 } else { reproducible_hash_one(&value.0.unwrap()) };
34 let second = if value.1.is_none() { 0 } else { reproducible_hash_one(&value.1.unwrap()) };
35 let third = if value.2.is_none() { 0 } else { reproducible_hash_one(&value.2.unwrap()) };
36
37 return Self { goal_ir: [first, second, third] }
38 }
39}
40
41pub(crate) fn pattern_match(goal: &EncodedGoal, fact: &EncodedFact) -> bool {
42 let first_goal_constant = byteorder::NativeEndian::read_u24(get_ith_term(goal, 0).1);
43 let first_fact_constant = byteorder::NativeEndian::read_u24(get_ith_term(fact, 0).1) >> 1;
44 if first_goal_constant != 0 && first_goal_constant != first_fact_constant {
45 return false
46 }
47
48 let second_goal_constant = byteorder::NativeEndian::read_u24(get_ith_term(goal, 1).1);
49 let second_fact_constant = byteorder::NativeEndian::read_u24(get_ith_term(fact, 1).1) >> 1;
50 if second_goal_constant != 0 && second_goal_constant != second_fact_constant {
51 return false
52 }
53
54 let third_goal_constant = byteorder::NativeEndian::read_u24(get_ith_term(goal, 2).1);
55 let third_fact_constant = byteorder::NativeEndian::read_u24(get_ith_term(fact, 2).1) >> 1;
56 if third_goal_constant != 0 && third_goal_constant != third_fact_constant {
57 return false
58 }
59
60 true
61}
62
63#[cfg(test)]
64mod tests {
65 use crate::builders::goal::pattern_match;
66 use crate::rewriting::atom::{encode_fact, encode_goal};
67
68 #[test]
69 fn test_pattern_match() {
70 let goal_one = encode_goal(&[1usize, 0, 0]);
71 let goal_two = encode_goal(&[0usize, 0, 0]);
72 let goal_three = encode_goal(&[467000usize, 510000, 511000]);
73
74 let fact_one = encode_fact(&[1usize, 4, 0]);
75 let fact_two = encode_fact(&[3usize, 4, 0]);
76 let fact_three = encode_fact(&[467000usize, 510000, 511000]);
77
78 assert!(pattern_match(&goal_one, &fact_one));
79 assert!(!pattern_match(&goal_one, &fact_two));
80 assert!(!pattern_match(&goal_one, &fact_three));
81
82 assert!(pattern_match(&goal_two, &fact_one));
83 assert!(pattern_match(&goal_two, &fact_two));
84 assert!(pattern_match(&goal_two, &fact_three));
85
86 assert!(!pattern_match(&goal_three, &fact_one));
87 assert!(!pattern_match(&goal_three, &fact_two));
88 assert!(pattern_match(&goal_three, &fact_three));
89 }
90}