From 193b8c8cacc83bf20e6e8e8159ee77776ccdb576 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Thu, 18 Jan 2024 19:32:49 +0100 Subject: [PATCH] implement MorphismBase, remove `data` from NestedNode --- examples/tty-02-node/src/main.rs | 189 ++++++------- lib-nested-core/src/edit_tree/node.rs | 68 +---- lib-nested-core/src/editors/integer/ctx.rs | 5 +- lib-nested-core/src/editors/list/editor.rs | 3 +- lib-nested-core/src/editors/typeterm/ctx.rs | 4 +- lib-nested-core/src/repr_tree/context.rs | 287 +------------------- lib-nested-core/src/repr_tree/mod.rs | 113 +------- lib-nested-core/src/repr_tree/morphism.rs | 105 +++++++ lib-nested-tty/src/editors/mod.rs | 81 ++++++ 9 files changed, 309 insertions(+), 546 deletions(-) create mode 100644 lib-nested-core/src/repr_tree/morphism.rs diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index d6199a8..2fe3791 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -7,87 +7,36 @@ extern crate termion; use { cgmath::Vector2, nested::{ - edit_tree::{NestedNode, TreeCursor, TreeNav}, - repr_tree::{Context, ReprTree}, - editors::ObjCommander + editors::ObjCommander, + repr_tree::{Context}, }, nested_tty::{ - terminal::TermOutWriter, DisplaySegment, Terminal, TerminalAtom, TerminalCompositor, - TerminalEvent, TerminalStyle, TerminalView, - TTYApplication + DisplaySegment, TTYApplication, + TerminalCompositor, TerminalStyle, TerminalView, }, r3vi::{ buffer::singleton::*, - view::{port::UpdateTask, singleton::*, sequence::*, ViewPort}, - projection::decorate_sequence::* }, - std::sync::{Arc, Mutex, RwLock}, - termion::event::{Event, Key}, + std::sync::{Arc, RwLock}, }; -fn node_make_char_view( - node: NestedNode -) -> NestedNode { - node.disp.view - .write().unwrap() - .insert_branch(ReprTree::new_leaf( - Context::parse(&node.ctx, "TerminalView"), - node.data - .read() - .unwrap() - .get_port::>() - .expect("unable to get Char-view") - .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) - .to_grid() - .into(), - )); - - node -} - -fn node_make_seq_view( - mut node: NestedNode -) -> NestedNode { - node.disp.view - .write().unwrap() - .insert_branch(ReprTree::new_leaf( - Context::parse(&node.ctx, "TerminalView"), - node.data - .read() - .unwrap() - .get_port::< dyn SequenceView >() - .expect("unable to get Seq-view") - .map(move |char_node| node_make_view(char_node.clone()).display_view() ) - .wrap(nested_tty::make_label("("), nested_tty::make_label(")")) - .to_grid_horizontal() - .flatten() - .into() - )); - node -} - -fn node_make_list_edit( - mut node: NestedNode -) -> NestedNode { - nested_tty::editors::list::PTYListStyle::for_node( &mut node, ("(", ",", ")") ); - nested_tty::editors::list::PTYListController::for_node( &mut node, None, None ); - - node -} - -fn node_make_view( - node: NestedNode -) -> NestedNode { - if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") { - node_make_char_view( node ) - } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "") { - node_make_seq_view( node ) - } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "") { - node_make_list_edit( node ) - } else { - eprintln!("couldnt add view"); - node +struct ParseDigit { radix: u32 }; +impl Morphism for ParseDigit { + fn new( + ctx: &Arc> + ) -> Self { + } + + fn setup_projection(&self, repr_tree: Arc>) { + if let Some( char_view ) = repr_tree.get_out(Context::parse(&ctx, "Char~")) { + + } + } +} + +get_morphism( ) -> Morphism { + } #[async_std::main] @@ -96,19 +45,36 @@ async fn main() { */ let ctx = Arc::new(RwLock::new(Context::default())); - /* Create a Char-Node with editor & view */ - let mut node1 = Context::make_node( + let mut char_obj = ReprTree::make_leaf( + Context::parse(&ctx, "Char"), + SingletonBuffer::new('X').get_port().into() + ); + + char_obj.insert_branch( + Context::parse(&ctx, "EditTree"), + SingletonBuffer::new( + + ) + ); + + let mut vec_obj = ReprTree::make_leaf( + Context::parse(&ctx, ""), + VecBuffer::new(vec!['a', 'b', 'c']).get_port().into() + ); + + let mut char_edit = Context::new_edit_tree( &ctx, // node type Context::parse(&ctx, "Char"), // depth SingletonBuffer::new(0).get_port(), - ).unwrap(); + ) + .unwrap(); // add a display view to the node - node1 = node_make_view( node1 ); + node1 = nested_tty::editors::node_make_tty_view(node1); /* Create a -Node with editor & view */ @@ -118,10 +84,25 @@ async fn main() { Context::parse(&ctx, ""), // depth SingletonBuffer::new(0).get_port(), - ).unwrap(); + ) + .unwrap(); // add a display view to the node - node2 = node_make_view( node2 ); + node2 = nested_tty::editors::node_make_tty_view(node2); + + /* Create a -Node with editor & view + */ + let mut node3 = Context::make_node( + &ctx, + // node type + Context::parse(&ctx, ">"), + // depth + SingletonBuffer::new(0).get_port(), + ) + .unwrap(); + + // add a display view to the node + node3 = nested_tty::editors::node_make_tty_view(node3); /* setup terminal */ @@ -130,13 +111,16 @@ async fn main() { */ let ctx = ctx.clone(); - let mut node1 = node1.clone(); - let mut node2 = node2.clone(); - move |ev| { + let node1 = node1.clone(); + let node2 = node2.clone(); + let node3 = node3.clone(); + move |ev| { let mut node1 = node1.clone(); let mut node2 = node2.clone(); - node1.send_cmd_obj( ev.to_repr_tree(&ctx) ); - node2.send_cmd_obj( ev.to_repr_tree(&ctx) ); + let mut node3 = node3.clone(); + node1.send_cmd_obj(ev.to_repr_tree(&ctx)); + node2.send_cmd_obj(ev.to_repr_tree(&ctx)); + node3.send_cmd_obj(ev.to_repr_tree(&ctx)); } }); @@ -144,7 +128,7 @@ async fn main() { */ let compositor = TerminalCompositor::new(app.port.inner()); - // add some views to the display compositor + // add some views to the display compositor compositor.write().unwrap().push( nested_tty::make_label("Hello World") .map_item(|p, a| { @@ -153,21 +137,40 @@ async fn main() { .offset(Vector2::new(5, 0)), ); - let label = ctx.read().unwrap().type_term_to_str( &node1.get_type() ); - compositor.write().unwrap() - .push(nested_tty::make_label( &label ).offset(Vector2::new(0, 2))); + let label = ctx.read().unwrap().type_term_to_str(&node1.get_type()); + compositor + .write() + .unwrap() + .push(nested_tty::make_label(&label).offset(Vector2::new(0, 2))); - compositor.write().unwrap() + compositor + .write() + .unwrap() .push(node1.display_view().offset(Vector2::new(15, 2))); + let label2 = ctx.read().unwrap().type_term_to_str(&node2.get_type()); + compositor + .write() + .unwrap() + .push(nested_tty::make_label(&label2).offset(Vector2::new(0, 3))); - let label2 = ctx.read().unwrap().type_term_to_str( &node2.get_type() ); - compositor.write().unwrap() - .push(nested_tty::make_label( &label2 ).offset(Vector2::new(0, 3))); - - compositor.write().unwrap() + compositor + .write() + .unwrap() .push(node2.display_view().offset(Vector2::new(15, 3))); + + let label3 = ctx.read().unwrap().type_term_to_str(&node3.get_type()); + compositor + .write() + .unwrap() + .push(nested_tty::make_label(&label3).offset(Vector2::new(0, 4))); + + compositor + .write() + .unwrap() + .push(node3.display_view().offset(Vector2::new(25, 4))); + /* write the changes in the view of `term_port` to the terminal */ app.show().await.expect("output error!"); diff --git a/lib-nested-core/src/edit_tree/node.rs b/lib-nested-core/src/edit_tree/node.rs index 84d0412..b60326a 100644 --- a/lib-nested-core/src/edit_tree/node.rs +++ b/lib-nested-core/src/edit_tree/node.rs @@ -52,9 +52,6 @@ pub struct NestedNode { /// context pub ctx: Arc>, - /// abstract data view - pub data: Arc>, - /// viewports for terminal display pub disp: NestedNodeDisplay, @@ -63,7 +60,7 @@ pub struct NestedNode { } impl NestedNode { - pub fn new(ctx: Arc>, data: Arc>, depth: OuterViewPort>) -> Self { + pub fn new(ctx: Arc>, depth: OuterViewPort>) -> Self { NestedNode { disp: NestedNodeDisplay { view: ReprTree::new_arc(Context::parse(&ctx, "Display")), @@ -74,43 +71,13 @@ impl NestedNode { editor: SingletonBuffer::new(None), spillbuf: Arc::new(RwLock::new(Vec::new())), cmd: SingletonBuffer::new(None), - close_char: SingletonBuffer::new(None), + close_char: SingletonBuffer::new(None), tree_nav: SingletonBuffer::new(None), }, - data, ctx } } - - /* TODO: move into separate file/module - */ - pub fn from_char(ctx: Arc>, c: char) -> NestedNode { - let buf = r3vi::buffer::singleton::SingletonBuffer::::new(c); - - NestedNode::new( - ctx.clone(), - ReprTree::new_leaf( - Context::parse(&ctx, "Char"), - buf.get_port().into() - ), - SingletonBuffer::new(0).get_port() - ) -// .set_editor(Arc::new(RwLock::new(buf))) - } - - - //\\//\\ - - pub fn morph(self, ty: TypeTerm) -> NestedNode { - Context::morph_node(self, ty) - } - - pub fn get_type(&self) -> TypeTerm { - self.data.read().unwrap().get_type().clone() - } - - //\\//\\ - + pub fn set_editor(mut self, editor: Arc) -> Self { self.edit.editor.set(Some(editor)); self @@ -137,33 +104,6 @@ impl NestedNode { self.disp.diag.clone().unwrap_or(ViewPort::new().into_outer()) } - pub fn get_data_port<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator) -> Option> - where V::Msg: Clone { - let ctx = self.ctx.clone(); - let type_ladder = type_str.map(|s| Context::parse(&ctx, s)); - - let repr_tree = ReprTree::descend_ladder(&self.data, type_ladder)?; - repr_tree.clone().read().unwrap() - .get_port::().clone() - } - - pub fn get_data_view<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator) -> Option> - where V::Msg: Clone { - self.get_data_port::(type_str)?.get_view() - } - - /* TODO - pub fn get_seq_view<'a, T: Clone>(&self, type_str: impl Iterator) -> Option>> { - self.get_data_view::>(type_str) - .unwrap() - .map({ - move |node| { - node.get_data_view::>().get() - } - }) - } - */ - pub fn get_edit(&self) -> Option>> { if let Some(edit) = self.edit.editor.get() { if let Ok(edit) = edit.downcast::>() { @@ -187,7 +127,7 @@ impl TreeType for NestedNode { } } } - */ +*/ impl TreeNav for NestedNode { fn get_cursor(&self) -> TreeCursor { diff --git a/lib-nested-core/src/editors/integer/ctx.rs b/lib-nested-core/src/editors/integer/ctx.rs index 214ef8c..86875d0 100644 --- a/lib-nested-core/src/editors/integer/ctx.rs +++ b/lib-nested-core/src/editors/integer/ctx.rs @@ -6,7 +6,7 @@ use { laddertypes::{TypeTerm}, crate::{ repr_tree::{Context}, - repr_tree::{MorphismTypePattern}, + repr_tree::{MorphismType}, editors::{ list::*, integer::* @@ -16,6 +16,7 @@ use { }; pub fn init_ctx(ctx: &mut Context) { + /* ctx.add_typename("MachineInt".into()); ctx.add_typename("u32".into()); ctx.add_typename("u64".into()); @@ -126,7 +127,7 @@ pub fn init_ctx(ctx: &mut Context) { } ) ); - +*/ ctx.add_typename("Date".into()); ctx.add_typename("ISO-8601".into()); ctx.add_typename("TimeSince".into()); diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 087861b..8619012 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -109,7 +109,7 @@ impl ListEditor { let e = editor.read().unwrap(); - let mut node = NestedNode::new(ctx, data, depth) + let mut node = NestedNode::new(ctx, depth) .set_editor(editor.clone()) .set_nav(editor.clone()) .set_cmd(editor.clone()) @@ -307,6 +307,7 @@ impl ListEditor { self.nexd(); let mut b = item.edit.spillbuf.write().unwrap(); + let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), self.depth.map(|d| d+1)).unwrap(); tail_node.goto(TreeCursor::home()); diff --git a/lib-nested-core/src/editors/typeterm/ctx.rs b/lib-nested-core/src/editors/typeterm/ctx.rs index 0039c8f..984bb19 100644 --- a/lib-nested-core/src/editors/typeterm/ctx.rs +++ b/lib-nested-core/src/editors/typeterm/ctx.rs @@ -4,7 +4,7 @@ use { }, laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context, MorphismTypePattern}, + repr_tree::{Context, MorphismType}, editors::{ list::{ListEditor, ListSegmentSequence}, typeterm::{State, TypeTermEditor} @@ -26,7 +26,7 @@ pub fn init_ctx(ctx: &mut Context) { ctx.add_list_typename("Type::Ladder".into()); // = T1~T2~... ctx.add_morphism( - MorphismTypePattern { src_tyid: ctx.get_typeid("List"), dst_tyid: ctx.get_typeid("Type").unwrap() }, + MorphismType { src_tyid: Context::parse(&ctx, ""), dst_tyid: Context::parse(&ctx, "Type") }, Arc::new(move |node, _dst_type:_| { let ctx : Arc> = Arc::new(RwLock::new(Context::with_parent(Some(node.ctx.clone())))); ctx.write().unwrap().meta_chars.push('~'); diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 56d331d..264e3cc 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -1,8 +1,8 @@ - use { +use { r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}}, laddertypes::{TypeDict, TypeTerm, TypeID}, crate::{ - repr_tree::{ReprTree}, + repr_tree::{ReprTree, MorphismType, GenericReprTreeMorphism, MorphismBase}, edit_tree::NestedNode }, std::{ @@ -13,129 +13,26 @@ //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -#[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, Debug)] -pub struct MorphismType { -// pub mode: MorphismMode, - pub src_type: Option, - pub dst_type: TypeTerm, -} - -#[derive(Clone, Hash, Eq, PartialEq)] -pub struct MorphismTypePattern { - pub src_tyid: Option, - pub dst_tyid: TypeID -} - -impl MorphismType { - pub fn to_str(&self, ctx: &Context) -> String { - format!("{:?} -> {:?}", - 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 { - format!("{:?} -> {:?}", - 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()))) - } -} - -impl From for MorphismTypePattern { - fn from(value: MorphismType) -> MorphismTypePattern { - 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!() - } - } - - MorphismTypePattern { - src_tyid: value.src_type.map(|x| strip(&x)), - dst_tyid: strip(&value.dst_type) - } - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - #[derive(Clone)] pub struct Context { /// assigns a name to every type pub type_dict: Arc>, + pub morphisms: MorphismBase, + /// named vertices of the graph - nodes: HashMap< String, NestedNode >, + nodes: HashMap< String, Arc> >, /// todo: beautify /// types that can be edited as lists + /// do we really need this? pub list_types: Vec< TypeID >, pub meta_chars: Vec< char >, - /// graph constructors - /// TODO: move into separate struct MorphismMap or something - morphisms: HashMap< - MorphismTypePattern, - Arc< - dyn Fn( NestedNode, TypeTerm ) -> Option - + Send + Sync - > - >, - /// recursion parent: Option>>, } -impl Default for Context { - fn default() -> Context { - let mut ctx = Context::new(); - - ctx.add_list_typename("Sequence"); - ctx.add_synonym("Seq", "Sequence"); - ctx.add_list_typename("SepSeq"); - ctx.add_typename("NestedNode"); - ctx.add_typename("TerminalEvent"); - - 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 - } -} - impl Context { pub fn with_parent(parent: Option>>) -> Self { Context { @@ -143,7 +40,7 @@ impl Context { Some(p) => p.read().unwrap().type_dict.clone(), None => Arc::new(RwLock::new(TypeDict::new())) }, - morphisms: HashMap::new(), + morphisms: MorphismBase::new(), nodes: HashMap::new(), list_types: match parent.as_ref() { Some(p) => p.read().unwrap().list_types.clone(), @@ -240,105 +137,20 @@ impl Context { pub fn type_term_to_str(&self, t: &TypeTerm) -> String { self.type_dict.read().unwrap().unparse(&t) } - - pub fn add_node_ctor(&mut self, tn: &str, mk_editor: Arc>, TypeTerm, OuterViewPort>) -> Option + Send + Sync>) { - let dict = self.type_dict.clone(); - let mut dict = dict.write().unwrap(); - - let tyid = - if let Some(tyid) = dict.get_typeid(&tn.into()) { - tyid - } else { - dict.add_typename(tn.into()) - }; - - let morphism_pattern = MorphismTypePattern { - src_tyid: None, - dst_tyid: tyid - }; - - drop(dict); - - self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type| { - mk_editor(node.ctx.clone(), dst_type, node.disp.depth) - })); - } - - pub fn add_morphism( - &mut self, - morph_type_pattern: MorphismTypePattern, - morph_fn: Arc< - dyn Fn( NestedNode, TypeTerm ) -> Option - + Send + Sync - > - ) { - self.morphisms.insert(morph_type_pattern, morph_fn); - } - - pub fn get_morphism(&self, ty: MorphismType) -> Option Option + Send + Sync>> { - let pattern = MorphismTypePattern::from(ty.clone()); - - if let Some(morphism) = self.morphisms.get( &pattern ) { - Some(morphism.clone()) - } else { - self.parent.as_ref()? - .read().unwrap() - .get_morphism(ty) - } - } - - pub fn make_node(ctx: &Arc>, type_term: TypeTerm, depth: OuterViewPort>) -> Option { - let mk_node = ctx.read().unwrap().get_morphism(MorphismType { - src_type: None, - dst_type: type_term.clone() - }).expect(&format!("morphism {}", ctx.read().unwrap().type_term_to_str(&type_term))); - - /* 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( - NestedNode::new(new_ctx, ReprTree::new_arc(type_term.clone()), depth), - type_term - ) - } - - pub fn morph_node(mut node: NestedNode, dst_type: TypeTerm) -> NestedNode { - let src_type = node.data.read().unwrap().get_type().clone(); - let pattern = MorphismType { src_type: Some(src_type), dst_type: dst_type.clone() }; - - /* it is not univesally true to always use ascend. - */ - node.data = - ReprTree::ascend( - &node.data, - dst_type.clone() - ); - - let m = node.ctx.read().unwrap().get_morphism(pattern.clone()); - if let Some(transform) = m { - if let Some(new_node) = transform(node.clone(), dst_type) { - new_node - } else { - node.clone() - } - } else { - node - } - } - /// adds an object without any representations pub fn add_obj(ctx: Arc>, name: String, typename: &str) { let type_tag = ctx.read().unwrap() .type_dict.write().unwrap() .parse(typename).unwrap(); +/* if let Some(node) = Context::make_node(&ctx, type_tag, SingletonBuffer::new(0).get_port()) { ctx.write().unwrap().nodes.insert(name, node); } +*/ } - pub fn get_obj(&self, name: &String) -> Option { + pub fn get_obj(&self, name: &String) -> Option< Arc> > { if let Some(obj) = self.nodes.get(name) { Some(obj.clone()) } else if let Some(parent) = self.parent.as_ref() { @@ -347,85 +159,6 @@ impl Context { 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 { - Arc::new(RwLock::new(ReprTree::new(dst_type))) - }; - - 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 - } -} - */ } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 758fea3..dc6e7d9 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -1,7 +1,9 @@ pub mod context; +pub mod morphism; pub use { - context::{Context, MorphismMode, MorphismType, MorphismTypePattern}, + context::{Context}, + morphism::{MorphismType, GenericReprTreeMorphism, MorphismBase} }; use { @@ -16,7 +18,7 @@ use { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> #[derive(Clone)] -pub struct ReprTree { +pub struct ReprTree { type_tag: TypeTerm, port: Option, branches: HashMap>>, @@ -97,6 +99,8 @@ impl ReprTree { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn get_port(&self) -> Option> where V::Msg: Clone, @@ -137,110 +141,5 @@ impl ReprTree { n.insert_branch(rt.clone()); Arc::new(RwLock::new(n)) } - -/* - 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 -} - */ } diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs new file mode 100644 index 0000000..cc08e05 --- /dev/null +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -0,0 +1,105 @@ +use { + laddertypes::{TypeTerm, TypeID}, + crate::{ + repr_tree::{ReprTree}, + }, + std::{ + sync::{Arc, RwLock}, + collections::HashMap + } +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +#[derive(Clone, Hash, PartialEq, Eq, Debug)] +pub struct MorphismType { + pub src_type: TypeTerm, + pub dst_type: TypeTerm, +} + +#[derive(Clone)] +pub struct GenericReprTreeMorphism { + morph_type: MorphismType, + repr_tree_op: Arc< + dyn Fn( Arc>, &HashMap ) + + Send + Sync + > +} + +#[derive(Clone)] +pub struct MorphismBase { + morphisms: Vec< GenericReprTreeMorphism > +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl MorphismBase { + pub fn new() -> Self { + MorphismBase { + morphisms: Vec::new() + } + } + + pub fn add_morphism( + &mut self, + morph_type: MorphismType, + repr_tree_op: impl Fn( Arc>, &HashMap ) + Send + Sync + ) { + self.morphisms.push( + GenericReprTreeMorphism { + morph_type, + repr_tree_op: Arc::new(repr_tree_op) + } + ); + } + + pub fn find_morphism( + &self, + src_type: &TypeTerm, + dst_type: &TypeTerm + ) -> Option<(&GenericReprTreeMorphism, HashMap)> { + for m in self.morphisms.iter() { + + let unification_problem = laddertypes::UnificationProblem::new( + vec![ + ( src_type.clone(), m.morph_type.src_type.clone() ), + ( dst_type.clone(), m.morph_type.dst_type.clone() ) + ] + ); + + if let Ok(σ) = unification_problem.solve() { + eprintln!("found matching morphism"); + return Some((m, σ)); + } + } + + None + } + + pub fn morph( + &self, + repr_tree: Arc>, + target_type: &TypeTerm + ) { + if let Some((m, σ)) = self.find_morphism( repr_tree.read().unwrap().get_type(), target_type ) { + (m.repr_tree_op)( repr_tree, &σ ); + } else { + eprintln!("could not find morphism"); + } + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> +/* +impl MorphismType { + pub fn to_str(&self, ctx: &Context) -> String { + format!("{:?} -> {:?}", + if let Some(t) = self.src_type.as_ref() { + ctx.type_dict.read().unwrap().unparse(t) + } else { + "None".into() + }, + ctx.type_dict.read().unwrap().unparse(&self.dst_type)) + } +} +*/ diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index dbaef38..dfc07ee 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -1,3 +1,84 @@ pub mod list; +use { + nested::{ + edit_tree::{NestedNode}, + repr_tree::{ReprTree, Context} + }, + r3vi::{ + view::{singleton::*, sequence::*}, + projection::decorate_sequence::* + }, + crate::{ + make_label, + DisplaySegment, + atom::TerminalAtom + } +}; + +pub fn node_make_char_view( + node: NestedNode +) -> NestedNode { + node.disp.view + .write().unwrap() + .insert_branch(ReprTree::new_leaf( + Context::parse(&node.ctx, "TerminalView"), + node.data + .read() + .unwrap() + .get_port::>() + .expect("unable to get Char-view") + .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) + .to_grid() + .into(), + )); + + node +} + +pub fn node_make_seq_view( + mut node: NestedNode +) -> NestedNode { + node.disp.view + .write().unwrap() + .insert_branch(ReprTree::new_leaf( + Context::parse(&node.ctx, "TerminalView"), + node.data + .read() + .unwrap() + .get_port::>() + .expect("unable to get Seq-view") + .map(move |char_node| node_make_tty_view(char_node.clone()).display_view() ) + .wrap(make_label("("), make_label(")")) + .to_grid_horizontal() + .flatten() + .into() + )); + node +} + +pub fn node_make_list_edit( + mut node: NestedNode +) -> NestedNode { + list::PTYListStyle::for_node( &mut node, ("(", "", ")") ); + list::PTYListController::for_node( &mut node, None, None ); + + node +} + +pub fn node_make_tty_view( + node: NestedNode +) -> NestedNode { + if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") { + node_make_char_view( node ) + } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "") { + node_make_seq_view( node ) + } else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "") { + node_make_list_edit( node ) + } else { + eprintln!("couldnt add view"); + node + } +} +