From 493b8a864c81b29722401b6f109c1cc4712477f3 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sun, 11 Aug 2024 22:50:48 +0200 Subject: [PATCH] morphism base: find shortest path instead of just some path --- src/morphism.rs | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/morphism.rs b/src/morphism.rs index 0796c91..33eafd5 100644 --- a/src/morphism.rs +++ b/src/morphism.rs @@ -17,6 +17,10 @@ pub struct MorphismType { pub trait Morphism : Sized { fn get_type(&self) -> MorphismType; fn list_map_morphism(&self, list_typeid: TypeID) -> Option< Self >; + + fn weight(&self) -> u64 { + 1 + } } #[derive(Clone)] @@ -134,41 +138,47 @@ impl MorphismBase { dst_types } - /* performs DFS to find a morphism-path for a given type - * will return the first matching path, not the shortest + /* try to find shortest morphism-path for a given type */ pub fn find_morphism_path(&self, ty: MorphismType) -> Option< Vec > { let ty = ty.normalize(); - let mut visited = Vec::new(); + let mut queue = vec![ - vec![ ty.src_type.clone().normalize() ] + (0, vec![ ty.src_type.clone().normalize() ]) ]; - while let Some(current_path) = queue.pop() { - let current_type = current_path.last().unwrap(); + while ! queue.is_empty() { + queue.sort_by( |&(w1,_),&(w2,_)| w2.cmp(&w1)); - if ! visited.contains( current_type ) { - visited.push( current_type.clone() ); + if let Some((current_weight, current_path)) = queue.pop() { + let current_type = current_path.last().unwrap(); for (h, t) in self.enum_morphisms_with_subtyping(¤t_type) { let tt = TypeTerm::Ladder( vec![ h, t ] ).normalize(); - if ! visited.contains( &tt ) { + if ! current_path.contains( &tt ) { let unification_result = crate::unification::unify(&tt, &ty.dst_type); - let mut new_path = current_path.clone(); + let morphism_weight = 1; + /* + { + self.find_morphism( &tt ).unwrap().0.get_weight() + }; + */ + + let new_weight = current_weight + morphism_weight; + let mut new_path = current_path.clone(); new_path.push( tt ); if let Ok(σ) = unification_result { new_path = new_path.into_iter().map( |mut t: TypeTerm| t.apply_substitution(&|x| σ.get(x).cloned()).clone() ).collect::>(); - return Some(new_path); } else { - queue.push( new_path ); + queue.push( (new_weight, new_path) ); } } }