lib-nested/nested/src/core/context.rs

382 lines
11 KiB
Rust
Raw Normal View History

use {
2021-11-19 12:19:52 +01:00
crate::core::{
type_term::{TypeDict, TypeTerm},
AnyOuterViewPort, OuterViewPort, View,
},
std::{
collections::HashMap,
2021-11-19 12:19:52 +01:00
sync::{Arc, RwLock},
},
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
2021-05-10 01:57:47 +02:00
#[derive(Clone)]
pub struct ReprTree {
port: Option<AnyOuterViewPort>,
2021-11-19 12:19:52 +01:00
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
2021-05-10 01:57:47 +02:00
}
impl ReprTree {
pub fn new() -> Self {
ReprTree {
port: None,
2021-11-19 12:19:52 +01:00
branches: HashMap::new(),
2021-05-10 01:57:47 +02:00
}
}
2021-11-19 12:19:52 +01:00
pub fn new_leaf(port: AnyOuterViewPort) -> Arc<RwLock<Self>> {
2021-05-10 01:57:47 +02:00
let mut tree = ReprTree::new();
tree.insert_leaf(vec![].into_iter(), port);
Arc::new(RwLock::new(tree))
}
2021-11-19 12:19:52 +01:00
pub fn insert_branch(&mut self, type_tag: TypeTerm, repr: Arc<RwLock<ReprTree>>) {
2021-05-10 01:57:47 +02:00
self.branches.insert(type_tag, repr);
}
pub fn insert_leaf(
&mut self,
mut type_ladder: impl Iterator<Item = TypeTerm>,
2021-11-19 12:19:52 +01:00
port: AnyOuterViewPort,
2021-05-10 01:57:47 +02:00
) {
if let Some(type_term) = type_ladder.next() {
if let Some(next_repr) = self.branches.get(&type_term) {
next_repr.write().unwrap().insert_leaf(type_ladder, port);
} else {
let mut next_repr = ReprTree::new();
next_repr.insert_leaf(type_ladder, port);
self.insert_branch(type_term, Arc::new(RwLock::new(next_repr)));
}
} else {
self.port = Some(port);
}
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
#[derive(Clone)]
pub struct Object {
2021-05-10 01:57:47 +02:00
pub type_tag: TypeTerm,
2021-11-19 12:19:52 +01:00
pub repr: Arc<RwLock<ReprTree>>,
}
impl Object {
2021-11-19 12:19:52 +01:00
pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
where
V::Msg: Clone,
{
Some(
self.repr
.read()
.unwrap()
.port
.clone()?
.downcast::<V>()
.ok()
.unwrap(),
)
2021-05-10 01:57:47 +02:00
}
pub fn downcast(&self, dst_type: TypeTerm) -> Option<Object> {
if let Some(repr) = self.repr.read().unwrap().branches.get(&dst_type) {
Some(Object {
type_tag: dst_type,
2021-11-19 12:19:52 +01:00
repr: repr.clone(),
2021-05-10 01:57:47 +02:00
})
} else {
None
}
}
2021-11-19 12:19:52 +01:00
fn downcast_ladder(&self, repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Object> {
repr_ladder.fold(Some(self.clone()), |s, t| s?.downcast(t.clone()))
}
2021-05-10 01:57:47 +02:00
pub fn add_iso_repr(
&self,
type_ladder: impl Iterator<Item = TypeTerm>,
2021-11-19 12:19:52 +01:00
morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
2021-05-10 01:57:47 +02:00
) {
let mut cur_repr = self.repr.clone();
2021-05-10 01:57:47 +02:00
for dst_type in type_ladder {
if let Some(next_repr) = self.repr.read().unwrap().branches.get(&dst_type) {
// go deeper
cur_repr = next_repr.clone();
} else {
// search for morphism constructor and insert new repr
let mut obj = None;
2021-05-10 01:57:47 +02:00
for src_type in cur_repr.read().unwrap().branches.keys() {
2021-11-19 12:19:52 +01:00
if let Some(ctor) = morphism_constructors.get(&MorphismType {
mode: MorphismMode::Iso,
src_type: src_type.clone(),
dst_type: dst_type.clone(),
}) {
let new_obj = ctor(Object {
type_tag: src_type.clone(),
repr: cur_repr
.read()
.unwrap()
.branches
.get(&src_type)
.unwrap()
.clone(),
});
2021-05-10 01:57:47 +02:00
assert!(new_obj.type_tag == dst_type);
obj = Some(new_obj);
break;
}
}
if let Some(obj) = obj {
2021-11-19 12:19:52 +01:00
cur_repr
.write()
.unwrap()
.insert_branch(obj.type_tag, obj.repr);
2021-05-10 01:57:47 +02:00
} else {
panic!("could not find matching isomorphism!");
}
}
}
}
2021-05-10 01:57:47 +02:00
pub fn add_mono_repr<'a>(
&self,
type_ladder: impl Iterator<Item = TypeTerm>,
2021-11-19 12:19:52 +01:00
morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
2021-05-10 01:57:47 +02:00
) {
let mut cur_type = self.type_tag.clone();
let mut cur_repr = self.repr.clone();
for dst_type in type_ladder {
if let Some(next_repr) = self.repr.read().unwrap().branches.get(&dst_type) {
// go deeper
cur_type = dst_type;
cur_repr = next_repr.clone();
} else {
2021-11-19 12:19:52 +01:00
if let Some(constructor) = morphism_constructors.get(&MorphismType {
mode: MorphismMode::Mono,
src_type: cur_type.clone(),
dst_type: dst_type.clone(),
}) {
let new_obj = constructor(Object {
type_tag: cur_type.clone(),
repr: cur_repr
.read()
.unwrap()
.branches
.get(&cur_type)
.unwrap()
.clone(),
});
2021-05-10 01:57:47 +02:00
assert!(new_obj.type_tag == dst_type);
2021-11-19 12:19:52 +01:00
cur_repr
.write()
.unwrap()
.insert_branch(new_obj.type_tag.clone(), new_obj.repr.clone());
2021-05-10 01:57:47 +02:00
cur_type = new_obj.type_tag;
cur_repr = new_obj.repr;
}
}
}
}
2021-05-10 01:57:47 +02:00
// replace with higher-level type in which self is a repr branch
pub fn epi_cast<'a>(
&self,
2021-05-13 16:22:30 +02:00
_type_ladder: impl Iterator<Item = TypeTerm>,
2021-11-19 12:19:52 +01:00
_morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
2021-05-10 01:57:47 +02:00
) {
2021-11-19 12:19:52 +01:00
// todo
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct TypeLadder(Vec<TypeTerm>);
2021-05-10 01:57:47 +02:00
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
pub enum MorphismMode {
/// Isomorphism
/// e.g. `( PositionalInteger 10 BigEndian ) <~> ( PositionalInteger 16 LittleEndian )`
Iso,
2021-05-10 01:57:47 +02:00
/// Monomorphism, i.e. injective functions,
/// upcast-view, downcast-control, semantic gain
/// e.g. `( Sequence ( Digit 16 ) ) ~> ( PositionalInteger 16 LittleEndian )`
Mono,
/// Epimorphsim, i.e. surjective functions,
/// upcast-control, downcast-view, possible loss of entropy
/// e.g. `( Ascii ) ~> ( Digit 16 )`
Epi,
/// Any other function
2021-11-19 12:19:52 +01:00
Any,
2021-05-10 01:57:47 +02:00
}
2021-05-10 01:57:47 +02:00
#[derive(Clone, Hash, PartialEq, Eq)]
pub struct MorphismType {
pub mode: MorphismMode,
pub src_type: TypeTerm,
2021-11-19 12:19:52 +01:00
pub dst_type: TypeTerm,
2021-05-10 01:57:47 +02:00
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct Context {
type_dict: TypeDict,
default_constructors: HashMap<TypeTerm, Box<dyn Fn() -> Object + Send + Sync>>,
morphism_constructors: HashMap<MorphismType, Box<dyn Fn(Object) -> Object + Send + Sync>>,
objects: HashMap<String, Object>,
2021-11-19 12:19:52 +01:00
parent: Option<Arc<RwLock<Context>>>,
}
impl Context {
2021-05-10 01:57:47 +02:00
pub fn with_parent(parent: Option<Arc<RwLock<Context>>>) -> Self {
Context {
type_dict: TypeDict::new(),
default_constructors: HashMap::new(),
morphism_constructors: HashMap::new(),
objects: HashMap::new(),
2021-11-19 12:19:52 +01:00
parent,
2021-05-10 01:57:47 +02:00
}
}
pub fn new() -> Self {
Context::with_parent(None)
}
pub fn add_typename(&mut self, tn: String) {
self.type_dict.add_typename(tn);
}
pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> {
self.type_dict.type_term_from_str(&tn)
}
pub fn add_morphism(
&mut self,
morph_type: MorphismType,
2021-11-19 12:19:52 +01:00
morph_fn: Box<dyn Fn(Object) -> Object + Send + Sync>,
2021-05-10 01:57:47 +02:00
) {
self.morphism_constructors.insert(morph_type, morph_fn);
}
/// adds an object without any representations
2021-11-19 12:19:52 +01:00
pub fn add_obj(&mut self, name: String, typename: &str) {
2021-05-10 01:57:47 +02:00
let type_tag = self.type_dict.type_term_from_str(typename).unwrap();
self.objects.insert(
name,
2021-05-10 01:57:47 +02:00
if let Some(ctor) = self.default_constructors.get(&type_tag) {
ctor()
} else {
Object {
type_tag,
2021-11-19 12:19:52 +01:00
repr: Arc::new(RwLock::new(ReprTree::new())),
2021-05-10 01:57:47 +02:00
}
2021-11-19 12:19:52 +01:00
},
);
}
2021-11-19 12:19:52 +01:00
pub fn get_obj(&self, name: &String) -> Option<Object> {
2021-05-10 01:57:47 +02:00
if let Some(obj) = self.objects.get(name) {
Some(obj.clone())
} else if let Some(parent) = self.parent.as_ref() {
parent.read().unwrap().get_obj(name)
} else {
None
}
}
2021-11-19 12:19:52 +01:00
pub fn get_obj_port<'a, V: View + ?Sized + 'static>(
2021-05-10 01:57:47 +02:00
&self,
name: &str,
2021-11-19 12:19:52 +01:00
type_ladder: impl Iterator<Item = &'a str>,
) -> Option<OuterViewPort<V>>
2021-11-19 12:19:52 +01:00
where
V::Msg: Clone,
{
2021-05-10 01:57:47 +02:00
self.get_obj(&name.into())?
2021-11-19 12:19:52 +01:00
.downcast_ladder(type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()))?
2021-05-10 01:57:47 +02:00
.get_port()
}
pub fn insert_repr<'a>(
&mut self,
name: &str,
type_ladder: impl Iterator<Item = &'a str>,
2021-11-19 12:19:52 +01:00
port: AnyOuterViewPort,
2021-05-10 01:57:47 +02:00
) {
2021-11-19 12:19:52 +01:00
self.get_obj(&name.to_string())
.unwrap()
.repr
.write()
.unwrap()
2021-05-10 01:57:47 +02:00
.insert_leaf(
type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()),
2021-11-19 12:19:52 +01:00
port,
2021-05-10 01:57:47 +02:00
);
}
2021-11-19 12:19:52 +01:00
pub fn epi_cast(&mut self, name: &str, typename: &str) {
2021-05-10 01:57:47 +02:00
let dst_type = self.type_dict.type_term_from_str(typename).unwrap();
2021-05-13 16:22:30 +02:00
let old_obj = self.objects.get(&name.to_string()).unwrap().clone();
2021-11-19 12:19:52 +01:00
let new_obj = if let Some(ctor) = self.morphism_constructors.get(&MorphismType {
mode: MorphismMode::Epi,
src_type: old_obj.type_tag.clone(),
dst_type: dst_type.clone(),
}) {
ctor(old_obj.clone())
} else {
Object {
type_tag: dst_type,
repr: Arc::new(RwLock::new(ReprTree::new())),
}
};
2021-11-19 12:19:52 +01:00
new_obj
.repr
.write()
.unwrap()
.insert_branch(old_obj.type_tag, old_obj.repr);
2021-05-10 01:57:47 +02:00
self.objects.insert(name.to_string(), new_obj);
}
pub fn mono_view<'a, V: View + ?Sized + 'static>(
&mut self,
name: &str,
2021-11-19 12:19:52 +01:00
type_ladder: impl Iterator<Item = &'a str>,
) -> Option<OuterViewPort<V>>
2021-11-19 12:19:52 +01:00
where
V::Msg: Clone,
{
2021-05-10 01:57:47 +02:00
if let Some(p) = self.get_obj_port(name, type_ladder) {
Some(p)
} else {
// todo : add repr with morphism constructor (if one exists)
/*
if let Some(ctor) = self.morphism_constructors.get(
&MorphismType {
mode: MorphismMode::Mono,
src_type: old_obj.type_tag.clone(),
2021-11-19 12:19:52 +01:00
dst_type:
2021-05-10 01:57:47 +02:00
}
)
*/
None
}
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>