automatic_relations/
lib.rs1#![feature(trait_alias)]
2
3extern crate terms;
4extern crate tree_automata as ta;
5
6use std::ops::Index;
7use std::cmp::{PartialOrd, Ord, Ordering};
8use std::slice::SliceIndex;
9use std::fmt;
10use terms::Term;
11use ta::Ranked;
12
13pub mod convolution;
14pub mod pattern;
15
16pub use convolution::Convolution;
17pub use pattern::ConvolutedPattern;
18
19#[derive(Debug, PartialEq, Eq, Clone, Hash)]
20pub struct Convoluted<T>(pub Vec<MaybeBottom<T>>);
21
22impl<T> Convoluted<T> {
23 pub fn iter(&self) -> std::slice::Iter<MaybeBottom<T>> {
24 self.0.iter()
25 }
26
27 pub fn len(&self) -> usize {
28 self.0.len()
29 }
30
31 pub fn signature(&self) -> u32 {
32 let mut signature: u32 = 0;
33 for t in &self.0 {
34 signature <<= 1;
35 if let MaybeBottom::Some(_) = t {
36 signature |= 1;
37 }
38 }
39
40 signature
41 }
42}
43
44impl<T, I> Index<I> for Convoluted<T> where I: SliceIndex<[MaybeBottom<T>]> {
45 type Output = I::Output;
46
47 fn index(&self, i: I) -> &I::Output {
48 self.0.index(i)
49 }
50}
51
52impl<T: Ord> Ord for Convoluted<T> {
53 fn cmp(&self, other: &Convoluted<T>) -> Ordering {
54 match self.0.len().cmp(&other.0.len()) {
55 Ordering::Equal => {
56 for (i, a) in self.0.iter().enumerate() {
57 let b = &other.0[i];
58 match a.cmp(b) {
59 Ordering::Equal => (),
60 ord => return ord
61 }
62 }
63
64 Ordering::Equal
65 },
66 ord => ord
67 }
68 }
69}
70
71impl<T: Ord> PartialOrd for Convoluted<T> {
72 fn partial_cmp(&self, other: &Convoluted<T>) -> Option<Ordering> {
73 Some(self.cmp(other))
74 }
75}
76
77#[derive(Debug, PartialEq, Eq, Clone, Hash)]
78pub enum MaybeBottom<T> {
79 Bottom,
80 Some(T)
81}
82
83impl<T: PartialEq> PartialEq<T> for MaybeBottom<T> {
84 fn eq(&self, other: &T) -> bool {
85 match self {
86 MaybeBottom::Some(t) => t == other,
87 _ => false
88 }
89 }
90}
91
92impl<T: Ord> Ord for MaybeBottom<T> {
93 fn cmp(&self, other: &MaybeBottom<T>) -> Ordering {
94 match (self, other) {
95 (MaybeBottom::Some(a), MaybeBottom::Some(b)) => a.cmp(b),
96 (MaybeBottom::Some(_), _) => Ordering::Greater,
97 (MaybeBottom::Bottom, MaybeBottom::Bottom) => Ordering::Equal,
98 _ => Ordering::Less
99 }
100 }
101}
102
103impl<T: Ord> PartialOrd for MaybeBottom<T> {
104 fn partial_cmp(&self, other: &MaybeBottom<T>) -> Option<Ordering> {
105 Some(self.cmp(other))
106 }
107}
108
109pub trait Relation<F: Ranked> {
110 fn contains(&self, terms: &[&Term<F>]) -> bool;
113}
114
115impl<T: fmt::Display> fmt::Display for MaybeBottom<T> {
116 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117 match self {
118 MaybeBottom::Bottom => write!(f, "⟘"),
119 MaybeBottom::Some(t) => t.fmt(f)
120 }
121 }
122}
123
124impl<T: fmt::Display> fmt::Display for Convoluted<T> {
125 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126 match self.0.split_first() {
127 Some((head, tail)) => {
128 head.fmt(f)?;
129 for e in tail.iter() {
130 write!(f, "⊗")?;
131 e.fmt(f)?;
132 }
133 Ok(())
134 },
135 None => Ok(())
136 }
137 }
138}