2023-11-28 17:16:51 +01:00
|
|
|
use {
|
2023-09-08 13:40:06 +02:00
|
|
|
r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}},
|
2023-11-12 18:07:20 +01:00
|
|
|
laddertypes::{TypeDict, TypeTerm, TypeID},
|
2022-05-08 23:30:49 +02:00
|
|
|
crate::{
|
2023-11-28 20:52:25 +01:00
|
|
|
repr_tree::{ReprTree},
|
|
|
|
edit_tree::NestedNode
|
2021-11-19 12:19:52 +01:00
|
|
|
},
|
2021-04-30 03:49:53 +02:00
|
|
|
std::{
|
|
|
|
collections::HashMap,
|
2021-11-19 12:19:52 +01:00
|
|
|
sync::{Arc, RwLock},
|
2021-04-30 03:49:53 +02:00
|
|
|
}
|
2023-01-02 13:18:55 +01:00
|
|
|
};
|
2021-04-30 03:49:53 +02:00
|
|
|
|
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
|
|
|
|
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-04-30 03:49:53 +02:00
|
|
|
|
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-04-30 03:49:53 +02:00
|
|
|
|
2023-08-15 23:18:51 +02:00
|
|
|
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
|
2021-05-10 01:57:47 +02:00
|
|
|
pub struct MorphismType {
|
2023-02-17 00:59:07 +01:00
|
|
|
// pub mode: MorphismMode,
|
|
|
|
pub src_type: Option<TypeTerm>,
|
2021-11-19 12:19:52 +01:00
|
|
|
pub dst_type: TypeTerm,
|
2021-05-10 01:57:47 +02:00
|
|
|
}
|
|
|
|
|
2023-08-15 23:18:51 +02:00
|
|
|
#[derive(Clone, Hash, Eq, PartialEq)]
|
2023-02-17 00:59:07 +01:00
|
|
|
pub struct MorphismTypePattern {
|
2023-02-20 03:40:37 +01:00
|
|
|
pub src_tyid: Option<TypeID>,
|
2023-02-17 00:59:07 +01:00
|
|
|
pub dst_tyid: TypeID
|
|
|
|
}
|
|
|
|
|
2023-08-15 23:18:51 +02:00
|
|
|
impl MorphismType {
|
|
|
|
pub fn to_str(&self, ctx: &Context) -> String {
|
2023-08-17 22:48:09 +02:00
|
|
|
format!("{:?} -> {:?}",
|
2023-08-15 23:18:51 +02:00
|
|
|
if let Some(t) = self.src_type.as_ref() {
|
|
|
|
ctx.type_term_to_str(t)
|
|
|
|
} else {
|
|
|
|
"None".into()
|
|
|
|
},
|
|
|
|
ctx.type_term_to_str(&self.dst_type))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MorphismTypePattern {
|
|
|
|
pub fn to_str(&self, ctx: &Context) -> String {
|
2023-08-17 22:48:09 +02:00
|
|
|
format!("{:?} -> {:?}",
|
2023-08-15 23:18:51 +02:00
|
|
|
if let Some(t) = self.src_tyid.as_ref() {
|
|
|
|
ctx.type_term_to_str(&TypeTerm::TypeID(t.clone()))
|
|
|
|
} else {
|
|
|
|
"None".into()
|
|
|
|
},
|
|
|
|
ctx.type_term_to_str(&TypeTerm::TypeID(self.dst_tyid.clone())))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-12 19:03:14 +02:00
|
|
|
impl From<MorphismType> for MorphismTypePattern {
|
2023-08-21 16:31:44 +02:00
|
|
|
fn from(value: MorphismType) -> MorphismTypePattern {
|
2023-08-12 19:03:14 +02:00
|
|
|
fn strip( x: &TypeTerm ) -> TypeID {
|
|
|
|
match x {
|
|
|
|
TypeTerm::TypeID(id) => id.clone(),
|
|
|
|
TypeTerm::App(args) => strip(&args[0]),
|
|
|
|
TypeTerm::Ladder(args) => strip(&args[0]),
|
|
|
|
_ => unreachable!()
|
|
|
|
}
|
|
|
|
}
|
2023-02-20 03:40:37 +01:00
|
|
|
|
2023-08-15 23:18:51 +02:00
|
|
|
MorphismTypePattern {
|
|
|
|
src_tyid: value.src_type.map(|x| strip(&x)),
|
2023-08-12 19:03:14 +02:00
|
|
|
dst_tyid: strip(&value.dst_type)
|
2023-02-17 00:59:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-10 01:57:47 +02:00
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
|
|
|
|
2023-05-19 11:26:05 +02:00
|
|
|
#[derive(Clone)]
|
2021-05-10 01:57:47 +02:00
|
|
|
pub struct Context {
|
2022-05-08 23:30:49 +02:00
|
|
|
/// assigns a name to every type
|
2023-03-02 03:43:38 +01:00
|
|
|
pub type_dict: Arc<RwLock<TypeDict>>,
|
2022-11-18 00:21:29 +01:00
|
|
|
|
2023-02-24 18:44:47 +01:00
|
|
|
/// named vertices of the graph
|
2023-02-17 00:59:07 +01:00
|
|
|
nodes: HashMap< String, NestedNode >,
|
2022-05-08 23:30:49 +02:00
|
|
|
|
2023-02-17 00:59:07 +01:00
|
|
|
/// todo: beautify
|
2023-02-13 18:39:45 +01:00
|
|
|
/// types that can be edited as lists
|
2023-05-19 11:26:05 +02:00
|
|
|
pub list_types: Vec< TypeID >,
|
|
|
|
pub meta_chars: Vec< char >,
|
2022-05-08 23:30:49 +02:00
|
|
|
|
2023-02-17 00:59:07 +01:00
|
|
|
/// graph constructors
|
2023-08-15 23:18:51 +02:00
|
|
|
/// TODO: move into separate struct MorphismMap or something
|
2023-02-17 00:59:07 +01:00
|
|
|
morphisms: HashMap<
|
|
|
|
MorphismTypePattern,
|
|
|
|
Arc<
|
2023-02-18 04:15:47 +01:00
|
|
|
dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
|
2023-02-17 00:59:07 +01:00
|
|
|
+ Send + Sync
|
|
|
|
>
|
|
|
|
>,
|
2022-05-08 23:30:49 +02:00
|
|
|
|
|
|
|
/// recursion
|
2021-11-19 12:19:52 +01:00
|
|
|
parent: Option<Arc<RwLock<Context>>>,
|
2021-04-30 03:49:53 +02:00
|
|
|
}
|
|
|
|
|
2023-08-21 15:49:07 +02:00
|
|
|
impl Default for Context {
|
|
|
|
fn default() -> Context {
|
|
|
|
let mut ctx = Context::new();
|
|
|
|
|
2023-09-04 06:17:14 +02:00
|
|
|
ctx.add_list_typename("Sequence");
|
|
|
|
ctx.add_synonym("Seq", "Sequence");
|
|
|
|
ctx.add_list_typename("SepSeq");
|
|
|
|
ctx.add_typename("NestedNode");
|
|
|
|
ctx.add_typename("TerminalEvent");
|
2023-08-21 15:49:07 +02:00
|
|
|
|
|
|
|
crate::editors::list::init_ctx( &mut ctx );
|
|
|
|
crate::editors::char::init_ctx( &mut ctx );
|
|
|
|
crate::editors::integer::init_ctx( &mut ctx );
|
|
|
|
crate::editors::typeterm::init_ctx( &mut ctx );
|
|
|
|
|
|
|
|
ctx
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-30 03:49:53 +02:00
|
|
|
impl Context {
|
2021-05-10 01:57:47 +02:00
|
|
|
pub fn with_parent(parent: Option<Arc<RwLock<Context>>>) -> Self {
|
|
|
|
Context {
|
2022-11-19 01:45:57 +01:00
|
|
|
type_dict: match parent.as_ref() {
|
|
|
|
Some(p) => p.read().unwrap().type_dict.clone(),
|
|
|
|
None => Arc::new(RwLock::new(TypeDict::new()))
|
|
|
|
},
|
2023-02-17 00:59:07 +01:00
|
|
|
morphisms: HashMap::new(),
|
|
|
|
nodes: HashMap::new(),
|
2023-02-13 18:39:45 +01:00
|
|
|
list_types: match parent.as_ref() {
|
|
|
|
Some(p) => p.read().unwrap().list_types.clone(),
|
|
|
|
None => Vec::new()
|
|
|
|
},
|
2023-05-19 11:26:05 +02:00
|
|
|
meta_chars: match parent.as_ref() {
|
|
|
|
Some(p) => p.read().unwrap().meta_chars.clone(),
|
|
|
|
None => Vec::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)
|
|
|
|
}
|
|
|
|
|
2023-02-17 00:59:07 +01:00
|
|
|
pub fn depth(&self) -> usize {
|
|
|
|
if let Some(parent) = self.parent.as_ref() {
|
|
|
|
parent.read().unwrap().depth() + 1
|
|
|
|
} else {
|
|
|
|
0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-12 18:07:20 +01:00
|
|
|
pub fn parse(ctx: &Arc<RwLock<Self>>, s: &str) -> TypeTerm {
|
|
|
|
ctx.read().unwrap().type_term_from_str(s).expect("could not parse type term")
|
|
|
|
}
|
|
|
|
|
2023-08-17 22:48:09 +02:00
|
|
|
pub fn add_typename(&mut self, tn: &str) -> TypeID {
|
|
|
|
self.type_dict.write().unwrap().add_typename(tn.to_string())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn add_varname(&mut self, vn: &str) -> TypeID {
|
|
|
|
self.type_dict.write().unwrap().add_varname(vn.to_string())
|
2023-02-13 18:39:45 +01:00
|
|
|
}
|
|
|
|
|
2023-09-04 06:17:14 +02:00
|
|
|
pub fn add_synonym(&mut self, new: &str, old: &str) {
|
|
|
|
self.type_dict.write().unwrap().add_synonym(new.to_string(), old.to_string());
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn add_list_typename(&mut self, tn: &str) {
|
|
|
|
let tid = self.add_typename(tn);
|
2023-02-13 18:39:45 +01:00
|
|
|
self.list_types.push( tid );
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_list_type(&self, t: &TypeTerm) -> bool {
|
|
|
|
match t {
|
2023-08-12 19:03:14 +02:00
|
|
|
TypeTerm::TypeID(id) => {
|
|
|
|
self.list_types.contains(id)
|
2023-02-13 18:39:45 +01:00
|
|
|
}
|
2023-09-15 15:15:59 +02:00
|
|
|
TypeTerm::Ladder(args) |
|
|
|
|
TypeTerm::App(args) => {
|
|
|
|
if args.len() > 0 {
|
|
|
|
if self.is_list_type(&args[0]) {
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
2023-02-13 18:39:45 +01:00
|
|
|
_ => false
|
|
|
|
}
|
2021-05-10 01:57:47 +02:00
|
|
|
}
|
|
|
|
|
2022-12-19 11:26:07 +01:00
|
|
|
pub fn get_typeid(&self, tn: &str) -> Option<TypeID> {
|
|
|
|
self.type_dict.read().unwrap().get_typeid(&tn.into())
|
|
|
|
}
|
|
|
|
|
2023-03-02 03:43:38 +01:00
|
|
|
pub fn get_fun_typeid(&self, tn: &str) -> Option<u64> {
|
|
|
|
match self.get_typeid(tn) {
|
|
|
|
Some(TypeID::Fun(x)) => Some(x),
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-12 19:03:14 +02:00
|
|
|
pub fn get_typename(&self, tid: &TypeID) -> Option<String> {
|
|
|
|
self.type_dict.read().unwrap().get_typename(tid)
|
|
|
|
}
|
|
|
|
|
2023-03-02 03:43:38 +01:00
|
|
|
pub fn get_var_typeid(&self, tn: &str) -> Option<u64> {
|
|
|
|
match self.get_typeid(tn) {
|
|
|
|
Some(TypeID::Var(x)) => Some(x),
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-12 18:07:20 +01:00
|
|
|
pub fn type_term_from_str(&self, tn: &str) -> Result<TypeTerm, laddertypes::parser::ParseError> {
|
|
|
|
self.type_dict.write().unwrap().parse(&tn)
|
2021-05-10 01:57:47 +02:00
|
|
|
}
|
2022-12-18 01:20:17 +01:00
|
|
|
|
2022-05-08 23:30:49 +02:00
|
|
|
pub fn type_term_to_str(&self, t: &TypeTerm) -> String {
|
2023-11-12 18:07:20 +01:00
|
|
|
self.type_dict.read().unwrap().unparse(&t)
|
2022-05-08 23:30:49 +02:00
|
|
|
}
|
2021-05-10 01:57:47 +02:00
|
|
|
|
2023-09-08 13:40:06 +02:00
|
|
|
pub fn add_node_ctor(&mut self, tn: &str, mk_editor: Arc<dyn Fn(Arc<RwLock<Self>>, TypeTerm, OuterViewPort<dyn SingletonView<Item = usize>>) -> Option<NestedNode> + Send + Sync>) {
|
2023-02-17 00:59:07 +01:00
|
|
|
let dict = self.type_dict.clone();
|
|
|
|
let mut dict = dict.write().unwrap();
|
2023-08-15 23:18:51 +02:00
|
|
|
|
2023-02-13 18:39:45 +01:00
|
|
|
let tyid =
|
|
|
|
if let Some(tyid) = dict.get_typeid(&tn.into()) {
|
|
|
|
tyid
|
|
|
|
} else {
|
|
|
|
dict.add_typename(tn.into())
|
|
|
|
};
|
2023-02-17 00:59:07 +01:00
|
|
|
|
|
|
|
let morphism_pattern = MorphismTypePattern {
|
2023-02-20 03:40:37 +01:00
|
|
|
src_tyid: None,
|
2023-02-17 00:59:07 +01:00
|
|
|
dst_tyid: tyid
|
|
|
|
};
|
|
|
|
|
2023-08-15 23:18:51 +02:00
|
|
|
drop(dict);
|
|
|
|
|
2023-02-18 04:15:47 +01:00
|
|
|
self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type| {
|
2023-09-08 13:40:06 +02:00
|
|
|
mk_editor(node.ctx.clone(), dst_type, node.depth)
|
2023-02-17 00:59:07 +01:00
|
|
|
}));
|
2022-05-08 23:30:49 +02:00
|
|
|
}
|
|
|
|
|
2023-02-17 00:59:07 +01:00
|
|
|
pub fn add_morphism(
|
|
|
|
&mut self,
|
|
|
|
morph_type_pattern: MorphismTypePattern,
|
|
|
|
morph_fn: Arc<
|
2023-02-18 04:15:47 +01:00
|
|
|
dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
|
2023-02-17 00:59:07 +01:00
|
|
|
+ Send + Sync
|
|
|
|
>
|
|
|
|
) {
|
|
|
|
self.morphisms.insert(morph_type_pattern, morph_fn);
|
|
|
|
}
|
|
|
|
|
2023-02-18 04:15:47 +01:00
|
|
|
pub fn get_morphism(&self, ty: MorphismType) -> Option<Arc<dyn Fn(NestedNode, TypeTerm) -> Option<NestedNode> + Send + Sync>> {
|
2023-02-17 00:59:07 +01:00
|
|
|
let pattern = MorphismTypePattern::from(ty.clone());
|
2023-08-15 23:18:51 +02:00
|
|
|
|
2023-02-17 00:59:07 +01:00
|
|
|
if let Some(morphism) = self.morphisms.get( &pattern ) {
|
|
|
|
Some(morphism.clone())
|
2022-05-08 23:30:49 +02:00
|
|
|
} else {
|
2023-02-17 00:59:07 +01:00
|
|
|
self.parent.as_ref()?
|
|
|
|
.read().unwrap()
|
|
|
|
.get_morphism(ty)
|
2022-05-08 23:30:49 +02:00
|
|
|
}
|
|
|
|
}
|
2022-11-13 15:26:25 +01:00
|
|
|
|
2023-09-08 13:40:06 +02:00
|
|
|
pub fn make_node(ctx: &Arc<RwLock<Self>>, type_term: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Option<NestedNode> {
|
2023-02-17 00:59:07 +01:00
|
|
|
let mk_node = ctx.read().unwrap().get_morphism(MorphismType {
|
|
|
|
src_type: None,
|
|
|
|
dst_type: type_term.clone()
|
2023-08-17 22:48:09 +02:00
|
|
|
}).expect(&format!("morphism {}", ctx.read().unwrap().type_term_to_str(&type_term)));
|
2023-02-17 00:59:07 +01:00
|
|
|
|
2023-08-15 23:18:51 +02:00
|
|
|
/* create new context per node ?? too heavy.. whats the reason? TODO */
|
|
|
|
|
|
|
|
let new_ctx = Arc::new(RwLock::new(Context::with_parent(Some(ctx.clone()))));
|
|
|
|
|
|
|
|
mk_node(
|
2023-09-06 05:50:48 +02:00
|
|
|
NestedNode::new(new_ctx, ReprTree::new_arc(type_term.clone()), depth),
|
2023-08-15 23:18:51 +02:00
|
|
|
type_term
|
|
|
|
)
|
2022-11-19 01:45:57 +01:00
|
|
|
}
|
|
|
|
|
2023-02-18 04:15:47 +01:00
|
|
|
pub fn morph_node(mut node: NestedNode, dst_type: TypeTerm) -> NestedNode {
|
2023-08-21 16:31:44 +02:00
|
|
|
let src_type = node.data.read().unwrap().get_type().clone();
|
2023-08-15 23:18:51 +02:00
|
|
|
let pattern = MorphismType { src_type: Some(src_type), dst_type: dst_type.clone() };
|
2023-08-17 22:48:09 +02:00
|
|
|
|
2023-08-15 23:18:51 +02:00
|
|
|
/* it is not univesally true to always use ascend.
|
|
|
|
*/
|
|
|
|
node.data =
|
|
|
|
ReprTree::ascend(
|
|
|
|
&node.data,
|
|
|
|
dst_type.clone()
|
2023-02-17 00:59:07 +01:00
|
|
|
);
|
2023-05-19 11:26:05 +02:00
|
|
|
|
2023-08-17 22:48:09 +02:00
|
|
|
let m = node.ctx.read().unwrap().get_morphism(pattern.clone());
|
2023-05-19 11:26:05 +02:00
|
|
|
if let Some(transform) = m {
|
2023-02-18 04:15:47 +01:00
|
|
|
if let Some(new_node) = transform(node.clone(), dst_type) {
|
2023-02-17 00:59:07 +01:00
|
|
|
new_node
|
|
|
|
} else {
|
|
|
|
node.clone()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
node
|
|
|
|
}
|
2021-05-10 01:57:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// adds an object without any representations
|
2023-02-17 00:59:07 +01:00
|
|
|
pub fn add_obj(ctx: Arc<RwLock<Context>>, name: String, typename: &str) {
|
|
|
|
let type_tag = ctx.read().unwrap()
|
2023-11-12 18:07:20 +01:00
|
|
|
.type_dict.write().unwrap()
|
|
|
|
.parse(typename).unwrap();
|
2021-05-10 01:57:47 +02:00
|
|
|
|
2023-09-08 13:40:06 +02:00
|
|
|
if let Some(node) = Context::make_node(&ctx, type_tag, SingletonBuffer::new(0).get_port()) {
|
2023-02-17 00:59:07 +01:00
|
|
|
ctx.write().unwrap().nodes.insert(name, node);
|
|
|
|
}
|
2021-04-30 03:49:53 +02:00
|
|
|
}
|
|
|
|
|
2023-02-17 00:59:07 +01:00
|
|
|
pub fn get_obj(&self, name: &String) -> Option<NestedNode> {
|
|
|
|
if let Some(obj) = self.nodes.get(name) {
|
2021-05-10 01:57:47 +02:00
|
|
|
Some(obj.clone())
|
|
|
|
} else if let Some(parent) = self.parent.as_ref() {
|
|
|
|
parent.read().unwrap().get_obj(name)
|
|
|
|
} else {
|
|
|
|
None
|
2021-04-30 03:49:53 +02:00
|
|
|
}
|
|
|
|
}
|
2021-11-19 12:19:52 +01:00
|
|
|
|
2022-11-18 00:21:29 +01:00
|
|
|
/*
|
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>,
|
2021-05-22 01:33:58 +02:00
|
|
|
) -> 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 {
|
2022-11-18 00:21:29 +01:00
|
|
|
Arc::new(RwLock::new(ReprTree::new(dst_type)))
|
2021-11-19 12:19:52 +01:00
|
|
|
};
|
2021-04-30 03:49:53 +02:00
|
|
|
|
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>,
|
2021-05-22 01:33:58 +02:00
|
|
|
) -> 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
|
|
|
|
}
|
2022-11-18 00:21:29 +01:00
|
|
|
}
|
|
|
|
*/
|
2021-04-30 03:49:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
2023-08-21 15:49:07 +02:00
|
|
|
|