|
|
|
@ -1,19 +1,12 @@
|
|
|
|
|
use {
|
|
|
|
|
crate::core::{
|
|
|
|
|
type_term::{TypeDict, TypeTerm},
|
|
|
|
|
AnyOuterViewPort, OuterViewPort, View,
|
|
|
|
|
},
|
|
|
|
|
std::{
|
|
|
|
|
collections::HashMap,
|
|
|
|
|
sync::{Arc, RwLock}
|
|
|
|
|
sync::{Arc, RwLock},
|
|
|
|
|
},
|
|
|
|
|
crate::{
|
|
|
|
|
core::{
|
|
|
|
|
type_term::{
|
|
|
|
|
TypeTerm,
|
|
|
|
|
TypeDict
|
|
|
|
|
},
|
|
|
|
|
View,
|
|
|
|
|
OuterViewPort,
|
|
|
|
|
AnyOuterViewPort
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
|
|
|
@ -21,37 +14,31 @@ use {
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
pub struct ReprTree {
|
|
|
|
|
port: Option<AnyOuterViewPort>,
|
|
|
|
|
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>
|
|
|
|
|
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ReprTree {
|
|
|
|
|
pub fn new() -> Self {
|
|
|
|
|
ReprTree {
|
|
|
|
|
port: None,
|
|
|
|
|
branches: HashMap::new()
|
|
|
|
|
branches: HashMap::new(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_leaf(
|
|
|
|
|
port: AnyOuterViewPort
|
|
|
|
|
) -> Arc<RwLock<Self>> {
|
|
|
|
|
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>>
|
|
|
|
|
) {
|
|
|
|
|
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
|
|
|
|
|
port: AnyOuterViewPort,
|
|
|
|
|
) {
|
|
|
|
|
if let Some(type_term) = type_ladder.next() {
|
|
|
|
|
if let Some(next_repr) = self.branches.get(&type_term) {
|
|
|
|
@ -72,39 +59,45 @@ impl ReprTree {
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
pub struct Object {
|
|
|
|
|
pub type_tag: TypeTerm,
|
|
|
|
|
pub repr: Arc<RwLock<ReprTree>>
|
|
|
|
|
pub repr: Arc<RwLock<ReprTree>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Object {
|
|
|
|
|
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())
|
|
|
|
|
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(),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
repr: repr.clone()
|
|
|
|
|
repr: repr.clone(),
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn downcast_ladder(
|
|
|
|
|
&self,
|
|
|
|
|
repr_ladder: impl Iterator<Item = TypeTerm>
|
|
|
|
|
) -> Option<Object> {
|
|
|
|
|
repr_ladder.fold(
|
|
|
|
|
Some(self.clone()),
|
|
|
|
|
|s, t| s?.downcast(t.clone())
|
|
|
|
|
)
|
|
|
|
|
fn downcast_ladder(&self, repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Object> {
|
|
|
|
|
repr_ladder.fold(Some(self.clone()), |s, t| s?.downcast(t.clone()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn add_iso_repr(
|
|
|
|
|
&self,
|
|
|
|
|
type_ladder: impl Iterator<Item = TypeTerm>,
|
|
|
|
|
morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>
|
|
|
|
|
morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
|
|
|
|
|
) {
|
|
|
|
|
let mut cur_repr = self.repr.clone();
|
|
|
|
|
|
|
|
|
@ -117,21 +110,21 @@ impl Object {
|
|
|
|
|
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()
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
@ -141,7 +134,10 @@ impl Object {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(obj) = obj {
|
|
|
|
|
cur_repr.write().unwrap().insert_branch(obj.type_tag, obj.repr);
|
|
|
|
|
cur_repr
|
|
|
|
|
.write()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.insert_branch(obj.type_tag, obj.repr);
|
|
|
|
|
} else {
|
|
|
|
|
panic!("could not find matching isomorphism!");
|
|
|
|
|
}
|
|
|
|
@ -152,7 +148,7 @@ impl Object {
|
|
|
|
|
pub fn add_mono_repr<'a>(
|
|
|
|
|
&self,
|
|
|
|
|
type_ladder: impl Iterator<Item = TypeTerm>,
|
|
|
|
|
morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>
|
|
|
|
|
morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
|
|
|
|
|
) {
|
|
|
|
|
let mut cur_type = self.type_tag.clone();
|
|
|
|
|
let mut cur_repr = self.repr.clone();
|
|
|
|
@ -163,24 +159,27 @@ impl Object {
|
|
|
|
|
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()
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
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_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;
|
|
|
|
@ -193,9 +192,9 @@ impl Object {
|
|
|
|
|
pub fn epi_cast<'a>(
|
|
|
|
|
&self,
|
|
|
|
|
_type_ladder: impl Iterator<Item = TypeTerm>,
|
|
|
|
|
_morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>
|
|
|
|
|
_morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
|
|
|
|
|
) {
|
|
|
|
|
// todo
|
|
|
|
|
// todo
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -220,14 +219,14 @@ pub enum MorphismMode {
|
|
|
|
|
Epi,
|
|
|
|
|
|
|
|
|
|
/// Any other function
|
|
|
|
|
Any
|
|
|
|
|
Any,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Hash, PartialEq, Eq)]
|
|
|
|
|
pub struct MorphismType {
|
|
|
|
|
pub mode: MorphismMode,
|
|
|
|
|
pub src_type: TypeTerm,
|
|
|
|
|
pub dst_type: TypeTerm
|
|
|
|
|
pub dst_type: TypeTerm,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
|
|
|
@ -237,7 +236,7 @@ pub struct Context {
|
|
|
|
|
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>,
|
|
|
|
|
parent: Option<Arc<RwLock<Context>>>
|
|
|
|
|
parent: Option<Arc<RwLock<Context>>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Context {
|
|
|
|
@ -247,7 +246,7 @@ impl Context {
|
|
|
|
|
default_constructors: HashMap::new(),
|
|
|
|
|
morphism_constructors: HashMap::new(),
|
|
|
|
|
objects: HashMap::new(),
|
|
|
|
|
parent
|
|
|
|
|
parent,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -266,17 +265,13 @@ impl Context {
|
|
|
|
|
pub fn add_morphism(
|
|
|
|
|
&mut self,
|
|
|
|
|
morph_type: MorphismType,
|
|
|
|
|
morph_fn: Box<dyn Fn(Object) -> Object + Send + Sync>
|
|
|
|
|
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(
|
|
|
|
|
&mut self,
|
|
|
|
|
name: String,
|
|
|
|
|
typename: &str
|
|
|
|
|
) {
|
|
|
|
|
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(
|
|
|
|
@ -286,16 +281,13 @@ impl Context {
|
|
|
|
|
} else {
|
|
|
|
|
Object {
|
|
|
|
|
type_tag,
|
|
|
|
|
repr: Arc::new(RwLock::new(ReprTree::new()))
|
|
|
|
|
repr: Arc::new(RwLock::new(ReprTree::new())),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn get_obj(
|
|
|
|
|
&self,
|
|
|
|
|
name: &String
|
|
|
|
|
) -> Option<Object> {
|
|
|
|
|
pub fn get_obj(&self, name: &String) -> Option<Object> {
|
|
|
|
|
if let Some(obj) = self.objects.get(name) {
|
|
|
|
|
Some(obj.clone())
|
|
|
|
|
} else if let Some(parent) = self.parent.as_ref() {
|
|
|
|
@ -304,20 +296,17 @@ impl Context {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn get_obj_port<
|
|
|
|
|
'a,
|
|
|
|
|
V: View + ?Sized + 'static
|
|
|
|
|
>(
|
|
|
|
|
|
|
|
|
|
pub fn get_obj_port<'a, V: View + ?Sized + 'static>(
|
|
|
|
|
&self,
|
|
|
|
|
name: &str,
|
|
|
|
|
type_ladder: impl Iterator<Item = &'a str>
|
|
|
|
|
type_ladder: impl Iterator<Item = &'a str>,
|
|
|
|
|
) -> Option<OuterViewPort<V>>
|
|
|
|
|
where V::Msg: Clone {
|
|
|
|
|
where
|
|
|
|
|
V::Msg: Clone,
|
|
|
|
|
{
|
|
|
|
|
self.get_obj(&name.into())?
|
|
|
|
|
.downcast_ladder(
|
|
|
|
|
type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap())
|
|
|
|
|
)?
|
|
|
|
|
.downcast_ladder(type_ladder.map(|tn| self.type_dict.type_term_from_str(tn).unwrap()))?
|
|
|
|
|
.get_port()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -325,43 +314,40 @@ impl Context {
|
|
|
|
|
&mut self,
|
|
|
|
|
name: &str,
|
|
|
|
|
type_ladder: impl Iterator<Item = &'a str>,
|
|
|
|
|
port: AnyOuterViewPort
|
|
|
|
|
port: AnyOuterViewPort,
|
|
|
|
|
) {
|
|
|
|
|
self.get_obj(&name.to_string()).unwrap()
|
|
|
|
|
.repr.write().unwrap()
|
|
|
|
|
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
|
|
|
|
|
port,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn epi_cast(
|
|
|
|
|
&mut self,
|
|
|
|
|
name: &str,
|
|
|
|
|
typename: &str
|
|
|
|
|
) {
|
|
|
|
|
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()))
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
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
|
|
|
|
|
);
|
|
|
|
|
new_obj
|
|
|
|
|
.repr
|
|
|
|
|
.write()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.insert_branch(old_obj.type_tag, old_obj.repr);
|
|
|
|
|
|
|
|
|
|
self.objects.insert(name.to_string(), new_obj);
|
|
|
|
|
}
|
|
|
|
@ -369,9 +355,11 @@ impl Context {
|
|
|
|
|
pub fn mono_view<'a, V: View + ?Sized + 'static>(
|
|
|
|
|
&mut self,
|
|
|
|
|
name: &str,
|
|
|
|
|
type_ladder: impl Iterator<Item = &'a str>
|
|
|
|
|
type_ladder: impl Iterator<Item = &'a str>,
|
|
|
|
|
) -> Option<OuterViewPort<V>>
|
|
|
|
|
where V::Msg: Clone {
|
|
|
|
|
where
|
|
|
|
|
V::Msg: Clone,
|
|
|
|
|
{
|
|
|
|
|
if let Some(p) = self.get_obj_port(name, type_ladder) {
|
|
|
|
|
Some(p)
|
|
|
|
|
} else {
|
|
|
|
@ -381,7 +369,7 @@ impl Context {
|
|
|
|
|
&MorphismType {
|
|
|
|
|
mode: MorphismMode::Mono,
|
|
|
|
|
src_type: old_obj.type_tag.clone(),
|
|
|
|
|
dst_type:
|
|
|
|
|
dst_type:
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
*/
|
|
|
|
@ -391,4 +379,3 @@ impl Context {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
|
|
|
|
|
|
|
|
|