Initial sketches
This commit is contained in:
commit
8e64a9c4a5
|
@ -0,0 +1,94 @@
|
|||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::hash_map::Iter;
|
||||
use std::collections::hash_map::Keys;
|
||||
use std::collections::hash_map::RandomState;
|
||||
use std::hash::BuildHasher;
|
||||
use std::hash::Hash;
|
||||
|
||||
type Count = i32;
|
||||
|
||||
pub enum Net {
|
||||
PresentToAbsent,
|
||||
AbsentToAbsent,
|
||||
AbsentToPresent,
|
||||
PresentToPresent,
|
||||
}
|
||||
|
||||
// Allows negative counts - a "delta"
|
||||
pub struct HashBag<V, S = RandomState> {
|
||||
counts: HashMap<V, Count, S>,
|
||||
}
|
||||
|
||||
impl<V,S> HashBag<V,S>
|
||||
where V: Eq + Hash, S: BuildHasher + Default
|
||||
{
|
||||
pub fn new() -> HashBag<V,S> {
|
||||
HashBag {
|
||||
counts: HashMap::with_hasher(Default::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn change(&mut self, key: V, delta: Count) -> Net { self._change(key, delta, false) }
|
||||
pub fn change_clamped(&mut self, key: V, delta: Count) -> Net { self._change(key, delta, true) }
|
||||
|
||||
pub fn _change(&mut self, key: V, delta: Count, clamp: bool) -> Net {
|
||||
let old_count = self[&key];
|
||||
let mut new_count = old_count + delta;
|
||||
if clamp { new_count = new_count.max(0) }
|
||||
if new_count == 0 {
|
||||
self.counts.remove(&key);
|
||||
if old_count == 0 { Net::AbsentToAbsent } else { Net::PresentToAbsent }
|
||||
} else {
|
||||
self.counts.insert(key, new_count);
|
||||
if old_count == 0 { Net::AbsentToPresent } else { Net::PresentToPresent }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.counts.clear();
|
||||
}
|
||||
|
||||
pub fn contains_key(&self, key: &V) -> bool {
|
||||
self.counts.contains_key(key)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.counts.is_empty()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.counts.len()
|
||||
}
|
||||
|
||||
pub fn keys(&self) -> Keys<V, Count> {
|
||||
self.counts.keys()
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> Iter<V, Count> {
|
||||
self.counts.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V,S> std::convert::From<HashSet<V, S>> for HashBag<V,S>
|
||||
where V: Eq + Hash + Clone, S: BuildHasher + Default
|
||||
{
|
||||
fn from(xs: HashSet<V,S>) -> Self {
|
||||
let mut cs = HashMap::with_hasher(Default::default());
|
||||
for k in xs.iter() {
|
||||
cs.insert(k.clone(), 1);
|
||||
}
|
||||
HashBag {
|
||||
counts: cs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<V,S> std::ops::Index<&V> for HashBag<V,S>
|
||||
where V: Eq + Hash, S: BuildHasher
|
||||
{
|
||||
type Output = Count;
|
||||
fn index(&self, i: &V) -> &Count {
|
||||
self.counts.get(i).unwrap_or(&0)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
mod term;
|
||||
mod bag;
|
||||
mod skeleton;
|
||||
|
||||
use self::term::Term;
|
||||
use self::skeleton::Index;
|
||||
|
||||
// Ord
|
||||
// Hash
|
||||
|
||||
fn main() {
|
||||
let capture_label = Term::Symbol("capture".to_string());
|
||||
let discard_label = Term::Symbol("discard".to_string());
|
||||
let v2 = Term::Double(1234.56);
|
||||
let v = Term::Seq(vec![
|
||||
Term::Boolean(true),
|
||||
Term::Float(123.34),
|
||||
v2.clone(),
|
||||
Term::SignedInteger(999),
|
||||
Term::SignedInteger(-101),
|
||||
Term::String("hello".to_string()),
|
||||
Term::ByteString("world".as_bytes()),
|
||||
Term::Symbol("sym".to_string()),
|
||||
Term::Rec(&capture_label, vec![
|
||||
Term::Rec(&discard_label, vec![]),
|
||||
]),
|
||||
]);
|
||||
let v3 = Term::Double(1234.57);
|
||||
println!("v = {:?}", v);
|
||||
println!("v[2] = {:?}", v[2]);
|
||||
println!("v == v = {:?}", v == v);
|
||||
println!("v3 == v = {:?}", v3 == v);
|
||||
println!("v[2] == v3 {:?}", v[2] == v3);
|
||||
println!("v[2] == v2 {:?}", v[2] == v2);
|
||||
println!("v[2] < v3 {:?}", v[2] < v3);
|
||||
println!("v[2] < v2 {:?}", v[2] < v2);
|
||||
println!("v[2] > v3 {:?}", v[2] > v3);
|
||||
println!("v[2] > v2 {:?}", v[2] > v2);
|
||||
println!("v[2] <= v3 {:?}", v[2] <= v3);
|
||||
println!("v[2] <= v2 {:?}", v[2] <= v2);
|
||||
println!("v[2] >= v3 {:?}", v[2] >= v3);
|
||||
println!("v[2] >= v2 {:?}", v[2] >= v2);
|
||||
println!("v == v3 {:?}", v == v3);
|
||||
println!("v == v2 {:?}", v == v2);
|
||||
println!("v < v3 {:?}", v < v3);
|
||||
println!("v < v2 {:?}", v < v2);
|
||||
println!("v > v3 {:?}", v > v3);
|
||||
println!("v > v2 {:?}", v > v2);
|
||||
println!("v <= v3 {:?}", v <= v3);
|
||||
println!("v <= v2 {:?}", v <= v2);
|
||||
println!("v >= v3 {:?}", v >= v3);
|
||||
println!("v >= v2 {:?}", v >= v2);
|
||||
println!("v[8].label() = {:?}", v[8].label());
|
||||
println!("v[8].len() = {:?}", v[8].len());
|
||||
println!("v[8][0] = {:?}", v[8][0]);
|
||||
println!("v[8][0].label() = {:?}", v[8][0].label());
|
||||
println!("v[8][0].len() = {:?}", v[8][0].len());
|
||||
println!("v.len() = {:?}", v.len());
|
||||
|
||||
let i = Index::new();
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
// use std::sync::Arc;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::bag::HashBag;
|
||||
use super::term::Term;
|
||||
|
||||
pub enum Event {
|
||||
Removed,
|
||||
Message,
|
||||
Added,
|
||||
}
|
||||
|
||||
type Path = Vec<usize>;
|
||||
type Paths = Vec<Path>;
|
||||
type Captures<'a> = Vec<Term<'a>>;
|
||||
|
||||
type Callback<'a> = FnMut(Event, Captures<'a>) -> ();
|
||||
|
||||
pub enum Skeleton<'a> {
|
||||
Blank,
|
||||
Guarded(Guard<'a>, Vec<Skeleton<'a>>)
|
||||
}
|
||||
|
||||
pub struct AnalysisResults<'a> {
|
||||
skeleton: Skeleton<'a>,
|
||||
constPaths: Paths,
|
||||
constVals: Vec<Term<'a>>,
|
||||
capturePaths: Captures<'a>,
|
||||
assertion: Term<'a>,
|
||||
}
|
||||
|
||||
pub struct Index<'a> {
|
||||
all_assertions: HashBag<Term<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Index<'a> {
|
||||
pub fn new() -> Self {
|
||||
Index {
|
||||
all_assertions: HashBag::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_handler(analysis_results: AnalysisResults,
|
||||
}
|
||||
|
||||
struct Node<'a> {
|
||||
continuation: Continuation<'a>,
|
||||
edges: HashMap<Selector, HashMap<Guard<'a>, Node<'a>>>,
|
||||
}
|
||||
|
||||
struct Continuation<'a> {
|
||||
cached_assertions: HashSet<Term<'a>>,
|
||||
leaf_map: HashMap<Paths, HashMap<Vec<Term<'a>>, Leaf<'a>>>,
|
||||
}
|
||||
|
||||
struct Selector {
|
||||
pop_count: usize,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
enum Guard<'a> {
|
||||
Rec(&'a Term<'a>, usize),
|
||||
Seq(usize),
|
||||
}
|
||||
|
||||
struct Leaf<'a> { // aka Topic
|
||||
cached_assertions: HashSet<Term<'a>>,
|
||||
handler_map: HashMap<Paths, Handler<'a>>,
|
||||
}
|
||||
|
||||
struct Handler<'a> {
|
||||
cached_captures: HashBag<Captures<'a>>,
|
||||
callbacks: HashSet<&'a Callback<'a>>,
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
use std::hash::Hash;
|
||||
use std::hash::Hasher;
|
||||
|
||||
#[derive(Debug, PartialOrd, Clone)]
|
||||
pub enum Term<'a> {
|
||||
Boolean(bool),
|
||||
Float(f32),
|
||||
Double(f64),
|
||||
SignedInteger(i64), // TODO: bignums
|
||||
String(std::string::String),
|
||||
ByteString(&'a [u8]),
|
||||
Symbol(std::string::String),
|
||||
|
||||
Rec(&'a Term<'a>, Vec<Term<'a>>),
|
||||
Seq(Vec<Term<'a>>),
|
||||
}
|
||||
|
||||
impl<'a> Term<'a> {
|
||||
pub fn is_rec(&self) -> bool { match self { Term::Rec(_, _) => true, _ => false } }
|
||||
pub fn is_seq(&self) -> bool { match self { Term::Seq(_) => true, _ => false } }
|
||||
|
||||
pub fn label(&self) -> &Term {
|
||||
match self {
|
||||
Term::Rec(l, _) => l,
|
||||
_ => panic!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
match self {
|
||||
Term::Seq(vs) => vs.len(),
|
||||
Term::Rec(_, fs) => fs.len(),
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::ops::Index<usize> for Term<'a> {
|
||||
type Output = Term<'a>;
|
||||
fn index(&self, i: usize) -> &Term<'a> {
|
||||
match self {
|
||||
Term::Seq(vs) => &vs[i],
|
||||
Term::Rec(_, fs) => &fs[i],
|
||||
_ => panic!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Eq for Term<'a> {}
|
||||
impl<'a> PartialEq for Term<'a> {
|
||||
fn eq(&self, other: &Term<'a>) -> bool {
|
||||
match (self, other) {
|
||||
(Term::Boolean(a), Term::Boolean(b)) => a == b,
|
||||
(Term::Float(a), Term::Float(b)) => a.to_bits() == b.to_bits(),
|
||||
(Term::Double(a), Term::Double(b)) => a.to_bits() == b.to_bits(),
|
||||
(Term::SignedInteger(a), Term::SignedInteger(b)) => a == b,
|
||||
(Term::String(a), Term::String(b)) => a == b,
|
||||
(Term::ByteString(a), Term::ByteString(b)) => a == b,
|
||||
(Term::Symbol(a), Term::Symbol(b)) => a == b,
|
||||
(Term::Seq(a), Term::Seq(b)) => a == b,
|
||||
(Term::Rec(la, fa), Term::Rec(lb, fb)) => la == lb && fa == fb,
|
||||
(_, _) => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Ord for Term<'a> {
|
||||
fn cmp(&self, other: &Term<'a>) -> std::cmp::Ordering {
|
||||
match (self, other) {
|
||||
(Term::Float(a), Term::Float(b)) => {
|
||||
let mut va: i32 = a.to_bits() as i32;
|
||||
let mut vb: i32 = b.to_bits() as i32;
|
||||
if va < 0 { va ^= 0x7fffffff; }
|
||||
if vb < 0 { vb ^= 0x7fffffff; }
|
||||
va.cmp(&vb)
|
||||
}
|
||||
(Term::Double(a), Term::Double(b)) => {
|
||||
let mut va: i64 = a.to_bits() as i64;
|
||||
let mut vb: i64 = b.to_bits() as i64;
|
||||
if va < 0 { va ^= 0x7fffffffffffffff; }
|
||||
if vb < 0 { vb ^= 0x7fffffffffffffff; }
|
||||
va.cmp(&vb)
|
||||
}
|
||||
(Term::Seq(a), Term::Seq(b)) => a.cmp(b),
|
||||
(Term::Rec(la, fa), Term::Rec(lb, fb)) => {
|
||||
match la.cmp(lb) {
|
||||
std::cmp::Ordering::Equal => fa.cmp(fb),
|
||||
o => o
|
||||
}
|
||||
}
|
||||
(_, _) => self.partial_cmp(other).expect("total order"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Hash for Term<'a> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
match self {
|
||||
Term::Boolean(b) => { 1.hash(state); b.hash(state) }
|
||||
Term::Float(f) => { 2.hash(state); f.to_bits().hash(state) }
|
||||
Term::Double(d) => { 3.hash(state); d.to_bits().hash(state) }
|
||||
Term::SignedInteger(i) => { 4.hash(state); i.hash(state) }
|
||||
Term::String(s) => { 5.hash(state); s.hash(state) }
|
||||
Term::ByteString(b) => { 6.hash(state); b.hash(state) }
|
||||
Term::Symbol(s) => { 7.hash(state); s.hash(state) }
|
||||
Term::Rec(l, fs) => { 8.hash(state); l.hash(state); fs.hash(state) }
|
||||
Term::Seq(vs) => { 9.hash(state); vs.hash(state) }
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue