Clean out term.rs, replaced by preserves; some adjustments to match; preserves TCP echo server

This commit is contained in:
Tony Garnock-Jones 2019-09-17 20:28:31 +01:00
parent 98b3b72b40
commit 366af6be33
4 changed files with 91 additions and 232 deletions

View File

@ -1,10 +1,7 @@
use std::collections::HashMap; use std::collections::BTreeMap;
use std::collections::HashSet; use std::collections::btree_map::Iter;
use std::collections::hash_map::Iter; use std::collections::btree_map::Keys;
use std::collections::hash_map::Keys; use std::iter::{FromIterator, IntoIterator};
use std::collections::hash_map::RandomState;
use std::hash::BuildHasher;
use std::hash::Hash;
type Count = i32; type Count = i32;
@ -16,17 +13,13 @@ pub enum Net {
} }
// Allows negative counts - a "delta" // Allows negative counts - a "delta"
pub struct HashBag<V, S = RandomState> { pub struct BTreeBag<V> where V: std::cmp::Ord {
counts: HashMap<V, Count, S>, counts: BTreeMap<V, Count>,
} }
impl<V,S> HashBag<V,S> impl<V> BTreeBag<V> where V: std::cmp::Ord {
where V: Eq + Hash, S: BuildHasher + Default pub fn new() -> BTreeBag<V> {
{ BTreeBag { counts: BTreeMap::new() }
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(&mut self, key: V, delta: Count) -> Net { self._change(key, delta, false) }
@ -64,29 +57,28 @@ where V: Eq + Hash, S: BuildHasher + Default
pub fn keys(&self) -> Keys<V, Count> { pub fn keys(&self) -> Keys<V, Count> {
self.counts.keys() self.counts.keys()
} }
}
pub fn iter(&self) -> Iter<V, Count> { impl<'a, V> IntoIterator for &'a BTreeBag<V> where V: std::cmp::Ord {
type Item = (&'a V, &'a Count);
type IntoIter = Iter<'a, V, Count>;
fn into_iter(self) -> Self::IntoIter {
self.counts.iter() self.counts.iter()
} }
} }
impl<V,S> std::convert::From<HashSet<V, S>> for HashBag<V,S> impl<V> FromIterator<V> for BTreeBag<V> where V: std::cmp::Ord {
where V: Eq + Hash + Clone, S: BuildHasher + Default fn from_iter<I: IntoIterator<Item=V>>(iter: I) -> Self {
{ let mut bag = Self::new();
fn from(xs: HashSet<V,S>) -> Self { for k in iter {
let mut cs = HashMap::with_hasher(Default::default()); bag.change(k, 1);
for k in xs.iter() {
cs.insert(k.clone(), 1);
}
HashBag {
counts: cs
} }
bag
} }
} }
impl<V,S> std::ops::Index<&V> for HashBag<V,S> impl<V> std::ops::Index<&V> for BTreeBag<V> where V: std::cmp::Ord {
where V: Eq + Hash, S: BuildHasher
{
type Output = Count; type Output = Count;
fn index(&self, i: &V) -> &Count { fn index(&self, i: &V) -> &Count {
self.counts.get(i).unwrap_or(&0) self.counts.get(i).unwrap_or(&0)

View File

@ -1,61 +1,40 @@
mod term;
mod bag; mod bag;
mod skeleton; mod skeleton;
use self::term::Term; use std::net::{TcpListener, TcpStream};
use self::skeleton::Index; use std::io::Result;
use preserves::value;
// Ord // use self::skeleton::Index;
// Hash
fn main() { mod packets {
let capture_label = Term::Symbol("capture".to_string()); #[derive(Debug, serde::Serialize, serde::Deserialize)]
let discard_label = Term::Symbol("discard".to_string()); pub struct Error(pub String);
let v2 = Term::Double(1234.56); }
let v = Term::Seq(vec![
Term::Boolean(true), fn handle_connection(mut stream: TcpStream) -> Result<()> {
Term::Float(123.34), println!("Got {:?}", &stream);
v2.clone(), let codec = value::Codec::without_placeholders();
Term::SignedInteger(999), loop {
Term::SignedInteger(-101), match codec.decode(&stream) {
Term::String("hello".to_string()), Ok(v) => codec.encoder(&mut stream).write(&v)?,
Term::ByteString("world".as_bytes()), Err(value::codec::Error::Eof) => break,
Term::Symbol("sym".to_string()), Err(value::codec::Error::Io(e)) => return Err(e),
Term::Rec(&capture_label, vec![ Err(value::codec::Error::Syntax(s)) => {
Term::Rec(&discard_label, vec![]), let v = value::to_value(packets::Error(s.to_string())).unwrap();
]), codec.encoder(&mut stream).write(&v)?;
]); break
let v3 = Term::Double(1234.57); }
println!("v = {:?}", v); }
println!("v[2] = {:?}", v[2]); }
println!("v == v = {:?}", v == v); Ok(())
println!("v3 == v = {:?}", v3 == v); }
println!("v[2] == v3 {:?}", v[2] == v3);
println!("v[2] == v2 {:?}", v[2] == v2); fn main() -> Result<()> {
println!("v[2] < v3 {:?}", v[2] < v3); // let i = Index::new();
println!("v[2] < v2 {:?}", v[2] < v2); let listener = TcpListener::bind("0.0.0.0:5889")?;
println!("v[2] > v3 {:?}", v[2] > v3); for stream in listener.incoming() {
println!("v[2] > v2 {:?}", v[2] > v2); handle_connection(stream?);
println!("v[2] <= v3 {:?}", v[2] <= v3); }
println!("v[2] <= v2 {:?}", v[2] <= v2); Ok(())
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();
} }

View File

@ -1,9 +1,7 @@
// use std::sync::Arc; use std::collections::BTreeMap;
use std::collections::HashMap; use std::collections::BTreeSet;
use std::collections::HashSet; use super::bag::BTreeBag;
use preserves::value::AValue;
use super::bag::HashBag;
use super::term::Term;
pub enum Event { pub enum Event {
Removed, Removed,
@ -13,45 +11,45 @@ pub enum Event {
type Path = Vec<usize>; type Path = Vec<usize>;
type Paths = Vec<Path>; type Paths = Vec<Path>;
type Captures<'a> = Vec<Term<'a>>; type Captures = Vec<AValue>;
type Callback<'a> = FnMut(Event, Captures<'a>) -> (); trait HandleEvent {
fn handle_event<'a>(self, captures: &Captures);
}
pub enum Skeleton<'a> { pub enum Skeleton {
Blank, Blank,
Guarded(Guard<'a>, Vec<Skeleton<'a>>) Guarded(Guard, Vec<Skeleton>)
} }
pub struct AnalysisResults<'a> { pub struct AnalysisResults {
skeleton: Skeleton<'a>, skeleton: Skeleton,
constPaths: Paths, const_paths: Paths,
constVals: Vec<Term<'a>>, const_vals: Vec<AValue>,
capturePaths: Captures<'a>, capture_paths: Paths,
assertion: Term<'a>, assertion: AValue,
} }
pub struct Index<'a> { pub struct Index {
all_assertions: HashBag<Term<'a>>, all_assertions: BTreeBag<AValue>,
} }
impl<'a> Index<'a> { impl Index {
pub fn new() -> Self { pub fn new() -> Self {
Index { Index{ all_assertions: BTreeBag::new() }
all_assertions: HashBag::new(),
}
} }
pub fn add_handler(analysis_results: AnalysisResults, // pub fn add_handler(analysis_results: AnalysisResults,
} }
struct Node<'a> { struct Node {
continuation: Continuation<'a>, continuation: Continuation,
edges: HashMap<Selector, HashMap<Guard<'a>, Node<'a>>>, edges: BTreeMap<Selector, BTreeMap<Guard, Node>>,
} }
struct Continuation<'a> { struct Continuation {
cached_assertions: HashSet<Term<'a>>, cached_assertions: BTreeSet<AValue>,
leaf_map: HashMap<Paths, HashMap<Vec<Term<'a>>, Leaf<'a>>>, leaf_map: BTreeMap<Paths, BTreeMap<Vec<AValue>, Leaf>>,
} }
struct Selector { struct Selector {
@ -59,17 +57,17 @@ struct Selector {
index: usize, index: usize,
} }
enum Guard<'a> { enum Guard {
Rec(&'a Term<'a>, usize), Rec(AValue, usize),
Seq(usize), Seq(usize),
} }
struct Leaf<'a> { // aka Topic struct Leaf { // aka Topic
cached_assertions: HashSet<Term<'a>>, cached_assertions: BTreeSet<AValue>,
handler_map: HashMap<Paths, Handler<'a>>, handler_map: BTreeMap<Paths, Handler>,
} }
struct Handler<'a> { struct Handler {
cached_captures: HashBag<Captures<'a>>, cached_captures: BTreeBag<Captures>,
callbacks: HashSet<&'a Callback<'a>>, callbacks: BTreeSet<Box<dyn HandleEvent>>,
} }

View File

@ -1,110 +0,0 @@
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) }
}
}
}