lib-nested/nested/src/type_system/repr_tree.rs

209 lines
6.4 KiB
Rust

use {
r3vi::view::{AnyOuterViewPort, OuterViewPort, View},
crate::{
type_system::{TypeTerm}
},
std::{
collections::HashMap,
sync::{Arc, RwLock},
},
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
#[derive(Clone)]
pub struct ReprTree {
type_tag: TypeTerm,
port: Option<AnyOuterViewPort>,
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
}
impl ReprTree {
pub fn new(type_tag: TypeTerm) -> Self {
ReprTree {
type_tag,
port: None,
branches: HashMap::new(),
}
}
pub fn get_type(&self) -> &TypeTerm {
&self.type_tag
}
pub fn new_leaf(type_tag: TypeTerm, port: AnyOuterViewPort) -> Arc<RwLock<Self>> {
let mut tree = ReprTree::new(type_tag);
tree.insert_leaf(vec![].into_iter(), port);
Arc::new(RwLock::new(tree))
}
pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) {
self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone());
}
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(type_term.clone());
next_repr.insert_leaf(type_ladder, port);
self.insert_branch(Arc::new(RwLock::new(next_repr)));
}
} else {
self.port = Some(port);
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
where
V::Msg: Clone,
{
Some(
self.port
.clone()?
.downcast::<V>()
.ok()
.unwrap()
)
}
pub fn get_view<V: View + ?Sized + 'static>(&self) -> Option<Arc<V>>
where
V::Msg: Clone,
{
self.get_port::<V>()?
.get_view()
}
pub fn descend(&self, dst_type: &TypeTerm) -> Option<Arc<RwLock<ReprTree>>> {
self.branches.get(dst_type).cloned()
}
pub fn descend_ladder(&self, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
let first = repr_ladder.next()?;
repr_ladder.fold(
self.descend(&first),
|s, t| s?.read().unwrap().descend(&t))
}
pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: TypeTerm) -> Arc<RwLock<ReprTree>> {
let mut n = Self::new(type_term);
n.insert_branch(rt.clone());
Arc::new(RwLock::new(n))
}
/*
pub fn add_iso_repr(
&self,
type_ladder: impl Iterator<Item = TypeTerm>,
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
}
*/
}