use { crate::core::{ type_term::{TypeDict, TypeTerm}, AnyOuterViewPort, OuterViewPort, View, }, std::{ collections::HashMap, sync::{Arc, RwLock}, }, }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> #[derive(Clone)] pub struct ReprTree { port: Option, branches: HashMap>>, } impl ReprTree { pub fn new() -> Self { ReprTree { port: None, branches: HashMap::new(), } } pub fn new_leaf(port: AnyOuterViewPort) -> Arc> { let mut tree = ReprTree::new(); tree.insert_leaf(vec![].into_iter(), port); Arc::new(RwLock::new(tree)) } pub fn insert_branch(&mut self, type_tag: TypeTerm, repr: Arc>) { self.branches.insert(type_tag, repr); } pub fn insert_leaf( &mut self, mut type_ladder: impl Iterator, port: AnyOuterViewPort, ) { 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 { pub type_tag: TypeTerm, pub repr: Arc>, } impl Object { pub fn get_port(&self) -> Option> where V::Msg: Clone, { Some( self.repr .read() .unwrap() .port .clone()? .downcast::() .ok() .unwrap(), ) } pub fn downcast(&self, dst_type: TypeTerm) -> Option { if let Some(repr) = self.repr.read().unwrap().branches.get(&dst_type) { Some(Object { type_tag: dst_type, repr: repr.clone(), }) } else { None } } fn downcast_ladder(&self, repr_ladder: impl Iterator) -> Option { repr_ladder.fold(Some(self.clone()), |s, t| s?.downcast(t.clone())) } pub fn add_iso_repr( &self, type_ladder: impl Iterator, morphism_constructors: &HashMap Object>>, ) { 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_repr = next_repr.clone(); } else { // search for morphism constructor and insert new repr let mut obj = None; for src_type in cur_repr.read().unwrap().branches.keys() { 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(), }); assert!(new_obj.type_tag == dst_type); obj = Some(new_obj); break; } } if let Some(obj) = obj { cur_repr .write() .unwrap() .insert_branch(obj.type_tag, obj.repr); } else { panic!("could not find matching isomorphism!"); } } } } pub fn add_mono_repr<'a>( &self, type_ladder: impl Iterator, morphism_constructors: &HashMap Object>>, ) { 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 { 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(), }); assert!(new_obj.type_tag == dst_type); cur_repr .write() .unwrap() .insert_branch(new_obj.type_tag.clone(), new_obj.repr.clone()); cur_type = new_obj.type_tag; cur_repr = new_obj.repr; } } } } // replace with higher-level type in which self is a repr branch pub fn epi_cast<'a>( &self, _type_ladder: impl Iterator, _morphism_constructors: &HashMap Object>>, ) { // todo } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub struct TypeLadder(Vec); #[derive(Clone, Copy, Hash, PartialEq, Eq)] pub enum MorphismMode { /// Isomorphism /// e.g. `( PositionalInteger 10 BigEndian ) <~> ( PositionalInteger 16 LittleEndian )` Iso, /// 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 Any, } #[derive(Clone, Hash, PartialEq, Eq)] pub struct MorphismType { pub mode: MorphismMode, pub src_type: TypeTerm, pub dst_type: TypeTerm, } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub struct Context { type_dict: TypeDict, default_constructors: HashMap Object + Send + Sync>>, morphism_constructors: HashMap Object + Send + Sync>>, objects: HashMap, parent: Option>>, } impl Context { pub fn with_parent(parent: Option>>) -> Self { Context { type_dict: TypeDict::new(), default_constructors: HashMap::new(), morphism_constructors: HashMap::new(), objects: HashMap::new(), parent, } } 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 { self.type_dict.type_term_from_str(&tn) } pub fn add_morphism( &mut self, morph_type: MorphismType, morph_fn: Box Object + Send + Sync>, ) { self.morphism_constructors.insert(morph_type, morph_fn); } /// adds an object without any representations pub fn add_obj(&mut self, name: String, typename: &str) { let type_tag = self.type_dict.type_term_from_str(typename).unwrap(); self.objects.insert( name, if let Some(ctor) = self.default_constructors.get(&type_tag) { ctor() } else { Object { type_tag, repr: Arc::new(RwLock::new(ReprTree::new())), } }, ); } pub fn get_obj(&self, name: &String) -> Option { 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 } } pub fn get_obj_port<'a, V: View + ?Sized + 'static>( &self, name: &str, type_ladder: impl Iterator, ) -> Option> where V::Msg: Clone, { self.get_obj(&name.into())? .downcast_ladder(type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()))? .get_port() } pub fn insert_repr<'a>( &mut self, name: &str, type_ladder: impl Iterator, port: AnyOuterViewPort, ) { self.get_obj(&name.to_string()) .unwrap() .repr .write() .unwrap() .insert_leaf( type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()), port, ); } pub fn epi_cast(&mut self, name: &str, typename: &str) { let dst_type = self.type_dict.type_term_from_str(typename).unwrap(); let old_obj = self.objects.get(&name.to_string()).unwrap().clone(); 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())), } }; new_obj .repr .write() .unwrap() .insert_branch(old_obj.type_tag, old_obj.repr); self.objects.insert(name.to_string(), new_obj); } pub fn mono_view<'a, V: View + ?Sized + 'static>( &mut self, name: &str, type_ladder: impl Iterator, ) -> Option> where V::Msg: Clone, { 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(), dst_type: } ) */ None } } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>