Progress on skeleton impl

This commit is contained in:
Tony Garnock-Jones 2019-10-22 22:37:37 +01:00
parent 3d48cebb91
commit e5afef28cc
5 changed files with 321 additions and 23 deletions

View File

@ -5,9 +5,9 @@ authors = ["Tony Garnock-Jones <tonyg@leastfixedpoint.com>"]
edition = "2018"
[dependencies]
preserves = "0.2.3"
preserves = "0.3.0"
serde = { version = "1.0", features = ["derive"] }
serde = { version = "1.0", features = ["derive", "rc"] }
serde_bytes = "0.11"
tokio = "0.2.0-alpha"

View File

@ -2,8 +2,9 @@ use std::collections::BTreeMap;
use std::collections::btree_map::{Iter, Keys, Entry};
use std::iter::{FromIterator, IntoIterator};
type Count = i32;
pub type Count = i32;
#[derive(Debug, PartialEq, Eq)]
pub enum Net {
PresentToAbsent,
AbsentToAbsent,

View File

@ -11,8 +11,24 @@ use preserves::value;
use std::sync::{Mutex, Arc};
use tokio::net::TcpListener;
use std::sync::atomic::{AtomicUsize, Ordering};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Syndicate {
Placeholder(usize),
}
impl value::Domain for Syndicate {}
static NEXT_PLACEHOLDER: AtomicUsize = AtomicUsize::new(0);
impl Syndicate {
pub fn new_placeholder() -> Self {
Self::Placeholder(NEXT_PLACEHOLDER.fetch_add(1, Ordering::SeqCst))
}
}
pub type ConnId = u64;
pub type V = value::ArcValue;
pub type V = value::ArcValue<Syndicate>;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {

View File

@ -1,12 +1,14 @@
use super::V;
use super::Syndicate;
use bytes::BytesMut;
use preserves::value;
use std::io;
use std::sync::Arc;
pub type EndpointName = V;
pub type Assertion = V;
pub type Captures = Vec<Assertion>;
pub type Captures = Arc<Vec<Assertion>>;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub enum Action {
@ -44,7 +46,7 @@ pub enum Out {
#[derive(Debug)]
pub enum DecodeError {
Read(value::decoder::Error),
Parse(value::error::Error, V),
Parse(value::error::Error<Syndicate>, V),
}
impl From<io::Error> for DecodeError {
@ -58,7 +60,7 @@ impl From<io::Error> for DecodeError {
#[derive(Debug)]
pub enum EncodeError {
Write(value::encoder::Error),
Unparse(value::error::Error),
Unparse(value::error::Error<Syndicate>),
}
impl From<io::Error> for EncodeError {
@ -67,8 +69,8 @@ impl From<io::Error> for EncodeError {
}
}
impl From<value::error::Error> for EncodeError {
fn from(v: value::error::Error) -> Self {
impl From<value::error::Error<Syndicate>> for EncodeError {
fn from(v: value::error::Error<Syndicate>) -> Self {
EncodeError::Unparse(v)
}
}
@ -86,11 +88,11 @@ impl From<EncodeError> for io::Error {
//---------------------------------------------------------------------------
pub struct Codec {
codec: value::Codec<V>,
codec: value::Codec<V, Syndicate>,
}
impl Codec {
pub fn new(codec: value::Codec<V>) -> Self {
pub fn new(codec: value::Codec<V, Syndicate>) -> Self {
Codec { codec }
}
}

View File

@ -1,4 +1,6 @@
use super::ConnId;
use super::Syndicate;
use super::bag;
use super::packets::Assertion;
use super::packets::Captures;
use super::packets::EndpointName;
@ -6,13 +8,16 @@ use super::packets::Event;
use preserves::value::{Map, Set, Value, NestedValue};
use std::collections::btree_map::Entry;
use std::iter::FromIterator;
use std::sync::Arc;
type Bag<A> = super::bag::BTreeBag<A>;
type Bag<A> = bag::BTreeBag<A>;
type Path = Vec<usize>;
type Paths = Vec<Path>;
type Events = Vec<(Vec<Endpoint>, Captures)>;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct Endpoint {
connection: ConnId,
name: EndpointName,
@ -24,16 +29,16 @@ pub enum Skeleton {
}
pub struct AnalysisResults {
skeleton: Skeleton,
const_paths: Paths,
const_vals: Vec<Assertion>,
capture_paths: Paths,
assertion: Assertion,
pub skeleton: Skeleton,
pub const_paths: Paths,
pub const_vals: Captures,
pub capture_paths: Paths,
pub assertion: Assertion,
}
#[derive(Debug)]
pub struct Index {
all_assertions: Bag<Assertion>,
all_assertions: Bag<CachedAssertion>,
root: Node,
}
@ -105,6 +110,61 @@ impl Index {
}
}
}
fn insert(&mut self, v: CachedAssertion) -> Events {
self.adjust(v, 1)
}
fn remove(&mut self, v: CachedAssertion) -> Events {
self.adjust(v, -1)
}
fn adjust(&mut self, outer_value: CachedAssertion, delta: bag::Count) -> Events {
let mut outputs = Vec::new();
let net = self.all_assertions.change(outer_value.clone(), delta);
match net {
bag::Net::AbsentToPresent => {
Modification::new(
true,
&outer_value,
|c, v| { c.cached_assertions.insert(v.clone()); },
|l, v| { l.cached_assertions.insert(v.clone()); },
|es, cs| {
if es.cached_captures.change(cs.clone(), 1) == bag::Net::AbsentToPresent {
outputs.push((es.endpoints.iter().cloned().collect(), cs.clone()))
}
})
.perform(&mut self.root);
}
bag::Net::PresentToAbsent => {
Modification::new(
false,
&outer_value,
|c, v| { c.cached_assertions.remove(v); },
|l, v| { l.cached_assertions.remove(v); },
|es, cs| {
if es.cached_captures.change(cs.clone(), -1) == bag::Net::PresentToAbsent {
outputs.push((es.endpoints.iter().cloned().collect(), cs.clone()))
}
})
.perform(&mut self.root);
}
_ => ()
}
outputs
}
fn send(&mut self, outer_value: CachedAssertion) -> Events {
let mut outputs = Vec::new();
Modification::new(
false,
&outer_value,
|_c, _v| (),
|_l, _v| (),
|es, cs| outputs.push((es.endpoints.iter().cloned().collect(), cs.clone())))
.perform(&mut self.root);
outputs
}
}
#[derive(Debug)]
@ -153,6 +213,114 @@ impl Node {
}
}
#[derive(Debug)]
pub enum Stack<'a, T> {
Empty,
Item(T, &'a Stack<'a, T>)
}
impl<'a, T> Stack<'a, T> {
fn pop(&self) -> &Self {
match self {
Stack::Empty => panic!("Internal error: pop: Incorrect pop_count computation"),
Stack::Item(_, tail) => tail
}
}
fn top(&self) -> &T {
match self {
Stack::Empty => panic!("Internal error: top: Incorrect pop_count computation"),
Stack::Item(item, _) => item
}
}
}
struct Modification<'op, FCont, FLeaf, FEndpoints>
where FCont: FnMut(&mut Continuation, &CachedAssertion) -> (),
FLeaf: FnMut(&mut Leaf, &CachedAssertion) -> (),
FEndpoints: FnMut(&mut Endpoints, Captures) -> ()
{
create_leaf_if_absent: bool,
outer_value: &'op CachedAssertion,
restriction_paths: Option<&'op Paths>,
outer_value_term: &'op Assertion,
m_cont: FCont,
m_leaf: FLeaf,
m_endpoints: FEndpoints,
}
impl<'op, FCont, FLeaf, FEndpoints> Modification<'op, FCont, FLeaf, FEndpoints>
where FCont: FnMut(&mut Continuation, &CachedAssertion) -> (),
FLeaf: FnMut(&mut Leaf, &CachedAssertion) -> (),
FEndpoints: FnMut(&mut Endpoints, Captures) -> ()
{
fn new(create_leaf_if_absent: bool,
outer_value: &'op CachedAssertion,
m_cont: FCont,
m_leaf: FLeaf,
m_endpoints: FEndpoints) -> Self {
let (restriction_paths, outer_value_term) = outer_value.unpack();
Modification {
create_leaf_if_absent,
outer_value,
restriction_paths,
outer_value_term,
m_cont,
m_leaf,
m_endpoints,
}
}
fn perform(&mut self, n: &mut Node) {
self.node(n, &Stack::Item(self.outer_value_term, &Stack::Empty))
}
fn node(&mut self, n: &mut Node, term_stack: &Stack<&Assertion>) {
self.continuation(&mut n.continuation);
for (selector, table) in &mut n.edges {
let mut next_stack = term_stack;
for _ in 0..selector.pop_count { next_stack = next_stack.pop() }
let next_value = step(next_stack.top(), selector.index);
if let Some(next_class) = class_of(next_value) {
if let Some(next_node) = table.get_mut(&next_class) {
self.node(next_node, &Stack::Item(next_value, next_stack))
}
}
}
}
fn continuation(&mut self, c: &mut Continuation) {
(self.m_cont)(c, self.outer_value);
let mut empty_const_paths = Vec::new();
for (const_paths, const_val_map) in &mut c.leaf_map {
let const_vals = project_paths(self.outer_value_term, const_paths);
let leaf_opt = if self.create_leaf_if_absent {
Some(const_val_map.entry(const_vals.clone()).or_insert_with(Leaf::new))
} else {
const_val_map.get_mut(&const_vals)
};
if let Some(leaf) = leaf_opt {
(self.m_leaf)(leaf, self.outer_value);
for (capture_paths, endpoints) in &mut leaf.endpoints_map {
if is_unrestricted(&capture_paths, self.restriction_paths) {
(self.m_endpoints)(endpoints,
project_paths(self.outer_value_term, &capture_paths));
}
}
if leaf.is_empty() {
const_val_map.remove(&const_vals);
if const_val_map.is_empty() {
empty_const_paths.push(const_paths.clone());
}
}
}
}
for const_paths in empty_const_paths {
c.leaf_map.remove(&const_paths);
}
}
}
fn class_of(v: &Assertion) -> Option<Guard> {
match v.value() {
Value::Sequence(ref vs) => Some(Guard::Seq(vs.len())),
@ -169,8 +337,8 @@ fn project_path<'a>(v: &'a Assertion, p: &Path) -> &'a Assertion {
v
}
fn project_paths<'a>(v: &'a Assertion, ps: &Paths) -> Vec<Assertion> {
ps.iter().map(|p| project_path(v, p)).cloned().collect()
fn project_paths<'a>(v: &'a Assertion, ps: &Paths) -> Captures {
Arc::new(ps.iter().map(|p| project_path(v, p)).cloned().collect())
}
fn step(v: &Assertion, i: usize) -> &Assertion {
@ -184,7 +352,7 @@ fn step(v: &Assertion, i: usize) -> &Assertion {
#[derive(Debug)]
struct Continuation {
cached_assertions: Set<CachedAssertion>,
leaf_map: Map<Paths, Map<Vec<Assertion>, Leaf>>,
leaf_map: Map<Paths, Map<Captures, Leaf>>,
}
impl Continuation {
@ -205,6 +373,15 @@ pub enum Guard {
Seq(usize),
}
impl Guard {
fn arity(&self) -> usize {
match self {
Guard::Rec(_, s) => *s,
Guard::Seq(s) => *s
}
}
}
#[derive(Debug)]
struct Leaf { // aka Topic
cached_assertions: Set<CachedAssertion>,
@ -234,7 +411,7 @@ impl Endpoints {
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
enum CachedAssertion {
pub enum CachedAssertion {
VisibilityRestricted(Paths, Assertion),
Unrestricted(Assertion),
}
@ -262,3 +439,105 @@ fn is_unrestricted(capture_paths: &Paths, restriction_paths: Option<&Paths>) ->
panic!("Not yet implemented");
}
pub struct Analyzer {
const_paths: Paths,
const_vals: Vec<Assertion>,
capture_paths: Paths,
path: Path,
}
impl Analyzer {
pub fn analyze(a: &Assertion) -> AnalysisResults {
let mut z = Analyzer {
const_paths: Vec::new(),
const_vals: Vec::new(),
capture_paths: Vec::new(),
path: Vec::new(),
};
let skeleton = z.walk(a);
AnalysisResults {
skeleton,
const_paths: z.const_paths,
const_vals: Arc::new(z.const_vals),
capture_paths: z.capture_paths,
assertion: a.clone(),
}
}
fn walk(&mut self, mut a: &Assertion) -> Skeleton {
while let Some(fields) = a.value().as_simple_record("Capture", Some(1)) {
self.capture_paths.push(self.path.clone());
a = &fields[0];
}
if a.value().is_simple_record("Discard", Some(0)) {
return Skeleton::Blank;
} else {
match class_of(a) {
Some(cls) => {
let arity = cls.arity();
Skeleton::Guarded(cls,
(0..arity).map(|i| {
self.path.push(i);
let s = self.walk(step(a, i));
self.path.pop();
s
}).collect())
}
None => {
self.const_paths.push(self.path.clone());
self.const_vals.push(a.clone());
Skeleton::Blank
}
}
}
}
}
pub fn instantiate_assertion(a: &Assertion, cs: Captures) -> CachedAssertion {
let mut capture_paths = Vec::new();
let mut path = Vec::new();
let mut vs: Vec<Assertion> = (*cs).clone();
vs.reverse();
let instantiated = instantiate_assertion_walk(&mut capture_paths, &mut path, &mut vs, a);
CachedAssertion::VisibilityRestricted(capture_paths, instantiated)
}
fn instantiate_assertion_walk(capture_paths: &mut Paths,
path: &mut Path,
vs: &mut Vec<Assertion>,
a: &Assertion) -> Assertion {
if let Some(fields) = a.value().as_simple_record("Capture", Some(1)) {
capture_paths.push(path.clone());
let v = vs.pop().unwrap();
instantiate_assertion_walk(capture_paths, path, vs, &fields[0]);
return v;
}
if a.value().is_simple_record("Discard", Some(0)) {
return Value::Domain(Syndicate::new_placeholder()).wrap();
} else {
let f = |(i, aa)| {
path.push(i);
let vv = instantiate_assertion_walk(capture_paths,
path,
vs,
aa);
path.pop();
vv
};
match class_of(a) {
Some(Guard::Seq(_)) =>
Value::from(Vec::from_iter(a.value().as_sequence().unwrap()
.iter().enumerate().map(f)))
.wrap(),
Some(Guard::Rec(l, _)) =>
Value::record(l, a.value().as_record().unwrap().1
.iter().enumerate().map(f).collect())
.wrap(),
None =>
a.clone(),
}
}
}