more context implementation

This commit is contained in:
Michael Sippel 2021-05-10 01:57:47 +02:00
parent c162e63b1d
commit 5ec4773eb1
Signed by: senvas
GPG key ID: F96CF119C34B64A6
3 changed files with 399 additions and 77 deletions

View file

@ -5,128 +5,411 @@ use {
any::Any any::Any
}, },
crate::{ crate::{
bimap::Bimap, core::{
core::type_term::{TypeID, TypeTerm} type_term::{
TypeID,
TypeTerm,
TypeDict
},
View,
OuterViewPort,
AnyOuterViewPort
}
} }
}; };
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub enum ReprTree { #[derive(Clone)]
Leaf(Arc<dyn Any + Send + Sync>), pub struct ReprTree {
Branch(HashMap<TypeTerm, Arc<RwLock<ReprTree>>>) port: Option<AnyOuterViewPort>,
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>
}
impl ReprTree {
pub fn new() -> Self {
ReprTree {
port: None,
branches: HashMap::new()
}
}
pub fn new_leaf(
port: AnyOuterViewPort
) -> Arc<RwLock<Self>> {
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<RwLock<ReprTree>>
) {
self.branches.insert(type_tag, repr);
}
pub fn insert_leaf(
&mut self,
mut type_ladder: impl Iterator<Item = TypeTerm>,
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)] #[derive(Clone)]
pub struct Object { pub struct Object {
type_tag: TypeTerm, pub type_tag: TypeTerm,
repr: Arc<RwLock<ReprTree>> pub repr: Arc<RwLock<ReprTree>>
} }
impl Object { impl Object {
fn downcast(&self, repr_type: TypeTerm) -> Option<Object> { pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> {
match &*self.repr.read().unwrap() { Some(self.repr.read().unwrap().port.clone()?.downcast::<V>().unwrap())
ReprTree::Leaf(data) => }
if self.type_tag == repr_type {
Some(self.clone()) pub fn downcast(&self, dst_type: TypeTerm) -> Option<Object> {
} else { if let Some(repr) = self.repr.read().unwrap().branches.get(&dst_type) {
None Some(Object {
}, type_tag: dst_type,
ReprTree::Branch(reprs) => repr: repr.clone()
Some(Object{ })
type_tag: repr_type.clone(), } else {
repr: reprs.get(&repr_type)?.clone() None
})
} }
} }
fn downcast_chain<'a>( fn downcast_ladder(
&self, &self,
repr_chain: impl Iterator<Item = &'a TypeTerm> repr_ladder: impl Iterator<Item = TypeTerm>
) -> Option<Object> { ) -> Option<Object> {
repr_chain.fold( repr_ladder.fold(
Some(self.clone()), Some(self.clone()),
|s, t| s?.downcast(t.clone()) |s, t| s?.downcast(t.clone())
) )
} }
fn get_data<T: Any + Send + Sync>(&self) -> Option<Arc<T>> { pub fn add_iso_repr(
match &*self.repr.read().unwrap() { &self,
ReprTree::Leaf(data) => Arc::downcast::<T>(data.clone()).ok(), type_ladder: impl Iterator<Item = TypeTerm>,
_ => None morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> 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<Item = TypeTerm>,
morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> 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<Item = TypeTerm>,
morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>
) {
// todo
}
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct TypeDict { #[derive(Clone, Copy, Hash, PartialEq, Eq)]
typenames: Bimap::<String, u64>, pub enum MorphismMode {
type_id_counter: u64 /// 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
} }
impl TypeDict { #[derive(Clone, Hash, PartialEq, Eq)]
pub fn new() -> Self { pub struct MorphismType {
TypeDict { pub mode: MorphismMode,
typenames: Bimap::new(), pub src_type: TypeTerm,
type_id_counter: 0 pub dst_type: TypeTerm
}
}
pub fn add_typename(&mut self, tn: String) {
self.typenames.insert(tn, self.type_id_counter);
self.type_id_counter += 1;
}
pub fn type_term_from_str(&self, typename: &str) -> Option<TypeTerm> {
TypeTerm::from_str(typename, &self.typenames.)
}
pub fn type_term_to_str(&self, term: &TypeTerm) -> String {
term.to_str(&self.typenames.my)
}
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct Context { pub struct Context {
type_dict: TypeDict, type_dict: TypeDict,
default_constructors: HashMap<TypeTerm, Box<dyn Fn() -> Object + Send + Sync>>,
// map type_id -> constructor morphism_constructors: HashMap<MorphismType, Box<dyn Fn(Object) -> Object + Send + Sync>>,
constructors: HashMap<u64, Box<Fn() -> Arc<dyn Any + Send + Sync>>>, objects: HashMap<String, Object>,
parent: Option<Arc<RwLock<Context>>>
objects: HashMap<String, Object>
} }
impl Context { impl Context {
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(),
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<TypeTerm> {
self.type_dict.type_term_from_str(&tn)
}
pub fn add_morphism(
&mut self,
morph_type: MorphismType,
morph_fn: Box<dyn Fn(Object) -> Object + Send + Sync>
) {
self.morphism_constructors.insert(morph_type, morph_fn);
}
/// adds an object without any representations
pub fn add_obj( pub fn add_obj(
&mut self, &mut self,
name: String, name: String,
typename: &str typename: &str
) { ) {
let type_tag = self.type_dict.type_term_from_str(typename).unwrap();
self.objects.insert( self.objects.insert(
name, name,
Object { if let Some(ctor) = self.default_constructors.get(&type_tag) {
type_tag: self.type_dict.type_term_from_str(typename).unwrap(), ctor()
repr: Arc::new(RwLock::new(ReprTree::Branch(HashMap::new()))) } else {
Object {
type_tag,
repr: Arc::new(RwLock::new(ReprTree::new()))
}
} }
); );
} }
pub fn add_repr(&mut self, name: &String, typename: &str, repr: Arc<RwLock<ReprTree>>) { pub fn get_obj(
match &mut *self.objects.get_mut(name).unwrap().repr.write().unwrap() { &self,
ReprTree::Leaf(_) => {/*error*/}, name: &String
ReprTree::Branch(repr_map) => { ) -> Option<Object> {
repr_map.insert(self.type_dict.type_term_from_str(typename).unwrap(), repr.clone()); 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(&self, name: &String) -> Option<Object> { pub fn get_obj_port<
self.objects.get(name).cloned() 'a,
V: View + ?Sized + 'static
>(
&self,
name: &str,
type_ladder: impl Iterator<Item = &'a str>
) -> Option<OuterViewPort<V>> {
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<Item = &'a str>,
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 mut old_obj = self.objects.get(&name.to_string()).unwrap().clone();
let mut 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<Item = &'a str>
) -> Option<OuterViewPort<V>> {
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
}
}
/*
pub fn _default_repr<'a>(
&mut self,
name: &String,
type_ladder: impl Iterator<Item = &'a str>
) -> AnyOuterViewPort {
for (i, type_term) in type_ladder.rev().enumerate() {
match i {
0 => {
if let Some(constructor) = self.default_constructors.get(&type_term) {
self.add_repr()
} else {
panic!("cannot find matching default constructor!");
}
}
_n => {
}
}
}
}
*/
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View file

@ -25,17 +25,22 @@ pub use {
port::{ port::{
ViewPort, ViewPort,
InnerViewPort, InnerViewPort,
OuterViewPort OuterViewPort,
AnyViewPort,
AnyOuterViewPort,
AnyInnerViewPort,
}, },
type_term::{ type_term::{
TypeID, TypeID,
TypeTerm TypeTerm,
TypeDict,
}, },
context::{ context::{
ReprTree, ReprTree,
TypeDict, Object,
Context, Context,
Object MorphismMode,
MorphismType
} }
}; };

View file

@ -1,9 +1,14 @@
use std::{ use {
sync::Arc, std::{
any::Any, sync::Arc,
ops::Deref, any::Any,
collections::HashMap, ops::Deref,
iter::Peekable collections::HashMap,
iter::Peekable
},
crate::{
bimap::Bimap,
}
}; };
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
@ -131,3 +136,32 @@ impl TypeTerm {
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct TypeDict {
typenames: Bimap::<String, u64>,
type_id_counter: u64
}
impl TypeDict {
pub fn new() -> Self {
TypeDict {
typenames: Bimap::new(),
type_id_counter: 0
}
}
pub fn add_typename(&mut self, tn: String) {
self.typenames.insert(tn, self.type_id_counter);
self.type_id_counter += 1;
}
pub fn type_term_from_str(&self, typename: &str) -> Option<TypeTerm> {
TypeTerm::from_str(typename, &self.typenames.)
}
pub fn type_term_to_str(&self, term: &TypeTerm) -> String {
term.to_str(&self.typenames.my)
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>