morphism base: find shortest path instead of just some path

This commit is contained in:
Michael Sippel 2024-08-11 22:50:48 +02:00
parent e0334f4d5c
commit 493b8a864c
Signed by: senvas
GPG key ID: F96CF119C34B64A6

View file

@ -17,6 +17,10 @@ pub struct MorphismType {
pub trait Morphism : Sized { pub trait Morphism : Sized {
fn get_type(&self) -> MorphismType; fn get_type(&self) -> MorphismType;
fn list_map_morphism(&self, list_typeid: TypeID) -> Option< Self >; fn list_map_morphism(&self, list_typeid: TypeID) -> Option< Self >;
fn weight(&self) -> u64 {
1
}
} }
#[derive(Clone)] #[derive(Clone)]
@ -134,41 +138,47 @@ impl<M: Morphism + Clone> MorphismBase<M> {
dst_types dst_types
} }
/* performs DFS to find a morphism-path for a given type /* try to find shortest morphism-path for a given type
* will return the first matching path, not the shortest
*/ */
pub fn find_morphism_path(&self, ty: MorphismType) pub fn find_morphism_path(&self, ty: MorphismType)
-> Option< Vec<TypeTerm> > -> Option< Vec<TypeTerm> >
{ {
let ty = ty.normalize(); let ty = ty.normalize();
let mut visited = Vec::new();
let mut queue = vec![ let mut queue = vec![
vec![ ty.src_type.clone().normalize() ] (0, vec![ ty.src_type.clone().normalize() ])
]; ];
while let Some(current_path) = queue.pop() { while ! queue.is_empty() {
let current_type = current_path.last().unwrap(); queue.sort_by( |&(w1,_),&(w2,_)| w2.cmp(&w1));
if ! visited.contains( current_type ) { if let Some((current_weight, current_path)) = queue.pop() {
visited.push( current_type.clone() ); let current_type = current_path.last().unwrap();
for (h, t) in self.enum_morphisms_with_subtyping(&current_type) { for (h, t) in self.enum_morphisms_with_subtyping(&current_type) {
let tt = TypeTerm::Ladder( vec![ h, t ] ).normalize(); 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 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 ); new_path.push( tt );
if let Ok(σ) = unification_result { if let Ok(σ) = unification_result {
new_path = new_path.into_iter().map( new_path = new_path.into_iter().map(
|mut t: TypeTerm| t.apply_substitution(&|x| σ.get(x).cloned()).clone() |mut t: TypeTerm| t.apply_substitution(&|x| σ.get(x).cloned()).clone()
).collect::<Vec<TypeTerm>>(); ).collect::<Vec<TypeTerm>>();
return Some(new_path); return Some(new_path);
} else { } else {
queue.push( new_path ); queue.push( (new_weight, new_path) );
} }
} }
} }