rename morphism modules

This commit is contained in:
Michael Sippel 2025-06-12 05:05:19 +02:00
parent c73818c620
commit 821d233094
Signed by: senvas
GPG key ID: F96CF119C34B64A6
11 changed files with 346 additions and 255 deletions

View file

@ -52,9 +52,13 @@ impl Context {
impl TypeDict for Arc<RwLock<Context>> {
fn add_typename(&mut self, tn: &str) -> u64 {
let mut locked_self = self.write().unwrap();
let idx = locked_self.names.len();
locked_self.names.push(tn.into());
idx as u64
if let Some(parent) = locked_self.parent.as_mut() {
parent.add_typename(tn) + locked_self.names.len() as u64
} else {
let idx = locked_self.names.len();
locked_self.names.push(tn.into());
idx as u64
}
}
fn get_typeid(&self, tn: &str) -> Option<TypeID> {

View file

@ -5,7 +5,7 @@
pub mod term;
pub mod context;
pub mod constraint_system;
pub mod morphism_graph;
pub mod morphism;
#[cfg(test)]
mod test;
@ -15,5 +15,5 @@ pub use {
desugared_term::*,
term::*,
constraint_system::*,
morphism_graph::*,
morphism::*,
};

View file

@ -1,6 +1,6 @@
use {
crate::{
morphism_graph::{Morphism, MorphismInstance, MorphismType}, HashMapSubst, StructMember, TypeDict, TypeTerm
morphism::{Morphism, MorphismInstance, MorphismType}, HashMapSubst, StructMember, TypeDict, TypeTerm
}, std::io::Write
};

View file

@ -1,6 +1,6 @@
use {
crate::{
morphism_graph::DecomposedMorphismType, HashMapSubst, Morphism, MorphismBase, MorphismInstance, MorphismType, SubstitutionMut, TypeDict, TypeTerm
morphism::DecomposedMorphismType, EnumVariant, HashMapSubst, Morphism, MorphismBase, MorphismInstance, MorphismType, StructMember, SubstitutionMut, TypeDict, TypeTerm
},
std::{collections::HashMap, sync::{Arc,RwLock}}
};
@ -97,8 +97,8 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
Step::Inst { m } => m.get_weight(),
Step::Specialize { σ } => 0,
Step::MapSeq { item } => item.best_path_weight(),
Step::MapStruct { members } => todo!(),
Step::MapEnum { variants } => todo!(),
Step::MapStruct { members } => members.iter().map(|(_,g)| g.best_path_weight() ).sum(),
Step::MapEnum { variants } => variants.iter().map(|(_,g)| g.best_path_weight() ).max().unwrap_or(0),
}
}
@ -122,11 +122,10 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
item.get_solution().is_some()
}
Step::MapStruct { members } => {
//members.
todo!()
members.iter().map(|(s,g)| g.get_solution().is_some()).min().unwrap_or(true)
}
Step::MapEnum { variants } => {
todo!()
variants.iter().map(|(s,g)| g.get_solution().is_some()).min().unwrap_or(true)
}
Step::Inst { m } => true
}
@ -151,10 +150,10 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
let mut n = self.write().unwrap();
match &mut n.step {
Step::MapSeq { item } => {
eprintln!("advance seq-map");
//eprintln!("advance seq-map");
match item.advance(base, dict) {
GraphSearchState::Solved(item_morph) => {
eprintln!("Sequence-Map Sub Graph Solved!!");
//eprintln!("Sequence-Map Sub Graph Solved!!");
n.ty = MorphismType {
bounds: Vec::new(),
src_type: TypeTerm::Seq { seq_repr: None, items: vec![ item_morph.get_type().src_type ] },
@ -167,7 +166,18 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
}
}
Step::MapStruct { members } => {
todo!()
for (symbol, sub_search) in members.iter_mut() {
if sub_search.get_solution().is_none() {
match sub_search.advance(base, dict) {
GraphSearchState::Solved(_) => {
return Ok(true);
},
GraphSearchState::Continue => { return Ok(true); },
GraphSearchState::Err(err) => { return Err(err); }
}
}
}
return Ok(false);
}
Step::MapEnum { variants } => {
todo!()
@ -266,7 +276,11 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
Arc::new(RwLock::new(SearchNode {
pred: Some(self.clone()),
weight: self.get_weight(),
ty: todo!(),
ty: MorphismType {
bounds:Vec::new(),
src_type: TypeTerm::Struct { struct_repr: None, members: goals.iter().map(|(s,t)| StructMember{ symbol: s.clone(), ty: t.src_type.clone() }).collect() },
dst_type: TypeTerm::Struct { struct_repr: None, members: goals.iter().map(|(s,t)| StructMember{ symbol: s.clone(), ty: t.dst_type.clone() }).collect() }
},
step: Step::MapStruct { members: goals.into_iter().map(|(name,goal)| (name, GraphSearch::new(goal))).collect() },
ψ: self.read().unwrap().ψ.clone()
}))
@ -276,7 +290,11 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
Arc::new(RwLock::new(SearchNode {
pred: Some(self.clone()),
weight: self.get_weight(),
ty: todo!(),
ty: MorphismType {
bounds: Vec::new(),
src_type: TypeTerm::Enum { enum_repr: None, variants: goals.iter().map(|(s,t)| EnumVariant{ symbol: s.clone(), ty: t.src_type.clone() }).collect() },
dst_type: TypeTerm::Enum { enum_repr: None, variants: goals.iter().map(|(s,t)| EnumVariant{ symbol: s.clone(), ty: t.dst_type.clone() }).collect() }
},
step: Step::MapEnum { variants: goals.into_iter().map(|(name,goal)| (name, GraphSearch::new(goal))).collect() },
ψ: self.read().unwrap().ψ.clone()
}))
@ -304,14 +322,14 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
let mut begin = TypeTerm::unit();
let mut path = Vec::new();
eprintln!("to_morph_instance:\n==");
//eprintln!("to_morph_instance:\n==");
for (ψ, s) in steps {
match s {
SolvedStep::Id { τ } => {
eprintln!("to_morph_instance: ID {:?}", τ);
//eprintln!("to_morph_instance: ID {:?}", τ);
begin = τ.clone(); },
SolvedStep::Inst{ m } => {
eprintln!("to_morph_instance: Inst {:?} -- {:?}", ψ, m.get_type());
//eprintln!("to_morph_instance: Inst {:?} -- {:?}", ψ, m.get_type());
let mut m = m.clone();
if ! ψ.is_empty() {
m = MorphismInstance::Sub { ψ, m: Box::new(m) };
@ -319,7 +337,7 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
path.push(m.clone());
},
SolvedStep::Specialize { σ } => {
eprintln!("to_morph_instance: Specialize {:?}", σ);
//eprintln!("to_morph_instance: Specialize {:?}", σ);
if path.len() > 0 && !σ.is_empty() {
let m = MorphismInstance::from_chain(begin.clone(), &path);
path = vec![
@ -339,11 +357,25 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
path.push(m);
}
SolvedStep::MapStruct { members } => {
todo!();
//path.push(MorphismInstance::MapStruct { src_struct_repr: (), dst_struct_repr: (), member_morph: () })
let mut m = MorphismInstance::MapStruct {
src_struct_repr: None,
dst_struct_repr: None,
member_morph: members
};
if ! ψ.is_empty() {
m = MorphismInstance::Sub { ψ, m: Box::new(m) };
}
path.push(m);
}
SolvedStep::MapEnum { variants } => {
todo!();
let mut m = MorphismInstance::MapEnum {
enum_repr: None,
variant_morph: variants
};
if ! ψ.is_empty() {
m = MorphismInstance::Sub { ψ, m: Box::new(m) };
}
path.push(m);
}
}
}

View file

@ -1,4 +1,4 @@
use crate::{morphism_graph::MorphismType, TypeTerm};
use crate::{morphism::MorphismType, TypeTerm};
impl MorphismType {

View file

@ -1,234 +1,15 @@
pub mod morphism_base;
pub mod morphism_graph;
pub mod heuristic;
pub use morphism_base::*;
pub use morphism_graph::*;
use {
crate::{
constraint_system::ConstraintSystem, substitution::Substitution, term::{StructMember, TypeTerm},
unparser::*, EnumVariant, TypeDict, TypeID, VariableConstraint,
context::*
term::{StructMember, TypeTerm},
context::*,
morphism::*,
},
std::{
collections::HashMap,
sync::{Arc, RwLock}
}
std::collections::HashMap,
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct MorphismType {
pub bounds: Vec< VariableConstraint >,
pub src_type: TypeTerm,
pub dst_type: TypeTerm
}
impl MorphismType {
pub fn strip_common_rungs(&self) -> MorphismType {
match (&self.src_type.clone().strip(), &self.dst_type.clone().strip()) {
(TypeTerm::Ladder(rungs_lhs), TypeTerm::Ladder(rungs_rhs)) => {
let mut lhs_iter = rungs_lhs.iter();
let mut rhs_iter = rungs_rhs.iter();
let mut last = MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::unit(),
dst_type: TypeTerm::unit()
};
while let (Some(lhs_top), Some(rhs_top)) = (lhs_iter.next(), rhs_iter.next()) {
last.src_type = lhs_top.clone();
last.dst_type = rhs_top.clone();
if lhs_top != rhs_top {
let x = MorphismType {
bounds: Vec::new(),
src_type: lhs_top.clone(),
dst_type: rhs_top.clone()
}.strip_common_rungs();
let mut rl : Vec<_> = lhs_iter.cloned().collect();
rl.insert(0, x.src_type);
let mut rr : Vec<_> = rhs_iter.cloned().collect();
rr.insert(0, x.dst_type);
return MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Ladder(rl),
dst_type: TypeTerm::Ladder(rr)
};
}
}
last
}
(TypeTerm::Spec(args_lhs), TypeTerm::Spec(args_rhs)) => {
let (rl, rr) = args_lhs.iter().zip(args_rhs.iter()).map(
|(al,ar)| MorphismType{
bounds: Vec::new(),
src_type: al.clone(),
dst_type: ar.clone()
}.strip_common_rungs()
)
.fold((vec![], vec![]), |(mut rl, mut rr), x| {
rl.push(x.src_type);
rr.push(x.dst_type);
(rl,rr)
});
MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Spec(rl),
dst_type: TypeTerm::Spec(rr)
}
}
(TypeTerm::Seq { seq_repr:seq_repr_lhs, items:items_lhs },
TypeTerm::Seq { seq_repr: seq_repr_rhs, items:items_rhs })
=> {
let (rl, rr) = items_lhs.iter().zip(items_rhs.iter()).map(
|(al,ar)| MorphismType{
bounds: Vec::new(),
src_type: al.clone(),
dst_type: ar.clone()
}.strip_common_rungs()
)
.fold((vec![], vec![]), |(mut rl, mut rr), x| {
rl.push(x.src_type);
rr.push(x.dst_type);
(rl,rr)
});
MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Seq{ seq_repr: seq_repr_lhs.clone(), items: rl },
dst_type: TypeTerm::Seq { seq_repr: seq_repr_rhs.clone(), items: rr }
}
}
(TypeTerm::Struct { struct_repr:struct_repr_lhs, members:members_lhs },
TypeTerm::Struct { struct_repr: struct_repr_rhs, members:members_rhs })
=> {
let mut rl = Vec::new();
let mut rr = Vec::new();
for ar in members_rhs.iter() {
let mut found = false;
for al in members_lhs.iter() {
if al.symbol == ar.symbol {
let x = MorphismType{
bounds: Vec::new(),
src_type: al.ty.clone(),
dst_type: ar.ty.clone()
}.strip_common_rungs();
rl.push( StructMember{
symbol: al.symbol.clone(),
ty: x.src_type
});
rr.push( StructMember{
symbol: ar.symbol.clone(),
ty: x.dst_type
});
found = true;
break;
}
}
if !found {
return MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Struct { struct_repr: struct_repr_lhs.clone(), members:members_lhs.clone() },
dst_type: TypeTerm::Struct { struct_repr: struct_repr_rhs.clone(), members:members_rhs.clone() }
};
}
}
MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Struct{ struct_repr: struct_repr_lhs.clone(), members: rl },
dst_type: TypeTerm::Struct{ struct_repr: struct_repr_rhs.clone(), members: rr }
}
}
(TypeTerm::Enum { enum_repr:enum_repr_lhs, variants:variants_lhs },
TypeTerm::Enum { enum_repr: enum_repr_rhs, variants:variants_rhs })
=> {
let mut rl = Vec::new();
let mut rr = Vec::new();
for ar in variants_rhs.iter() {
let mut found = false;
for al in variants_lhs.iter() {
if al.symbol == ar.symbol {
let x = MorphismType {
bounds: self.bounds.clone(),
src_type: al.ty.clone(),
dst_type: ar.ty.clone()
}.strip_common_rungs();
rl.push( EnumVariant{
symbol: al.symbol.clone(),
ty: x.src_type
});
rr.push( EnumVariant{
symbol: ar.symbol.clone(),
ty: x.dst_type
});
found = true;
break;
}
}
if !found {
return MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Enum { enum_repr: enum_repr_lhs.clone(), variants:variants_lhs.clone() },
dst_type: TypeTerm::Enum { enum_repr: enum_repr_rhs.clone(), variants:variants_rhs.clone() }
};
}
}
MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Enum{ enum_repr: enum_repr_lhs.clone(), variants: rl },
dst_type: TypeTerm::Enum { enum_repr: enum_repr_rhs.clone(), variants: rr }
}
}
(x,y) => MorphismType { bounds: self.bounds.clone(), src_type: x.clone(), dst_type: y.clone() }
}
}
pub fn apply_subst(&self, σ: &impl Substitution) -> MorphismType {
MorphismType {
bounds: self.bounds.iter().map(|b| b.clone().apply_subst(σ).clone()).collect(),
src_type: self.src_type.clone().apply_subst(σ).clone(),
dst_type: self.dst_type.clone().apply_subst(σ).clone()
}
}
pub fn normalize(&self) -> MorphismType {
MorphismType {
bounds: self.bounds.iter().map(|bound| bound.normalize()).collect(),
src_type: self.src_type.clone().normalize(),
dst_type: self.dst_type.clone().normalize(),
}
}
}
pub trait Morphism : Sized {
fn get_type(&self) -> MorphismType;
fn weight(&self) -> u64 {
1
}
}
#[derive(Clone, PartialEq, Debug)]
pub enum MorphismInstance<M: Morphism + Clone> {
Id { τ: TypeTerm },

235
src/morphism/mod.rs Normal file
View file

@ -0,0 +1,235 @@
pub mod base;
pub mod graph;
pub mod instance;
pub mod heuristic;
pub use base::*;
pub use graph::*;
pub use instance::*;
use {
crate::{
constraint_system::ConstraintSystem, substitution::Substitution, term::{StructMember, TypeTerm},
unparser::*, EnumVariant, TypeDict, TypeID, VariableConstraint,
context::*
},
std::{
collections::HashMap,
sync::{Arc, RwLock}
}
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
pub trait Morphism : Sized {
fn get_type(&self) -> MorphismType;
fn weight(&self) -> u64 {
1
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct MorphismType {
pub bounds: Vec< VariableConstraint >,
pub src_type: TypeTerm,
pub dst_type: TypeTerm
}
impl MorphismType {
pub fn strip_common_rungs(&self) -> MorphismType {
match (&self.src_type.clone().strip(), &self.dst_type.clone().strip()) {
(TypeTerm::Ladder(rungs_lhs), TypeTerm::Ladder(rungs_rhs)) => {
let mut lhs_iter = rungs_lhs.iter();
let mut rhs_iter = rungs_rhs.iter();
let mut last = MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::unit(),
dst_type: TypeTerm::unit()
};
while let (Some(lhs_top), Some(rhs_top)) = (lhs_iter.next(), rhs_iter.next()) {
last.src_type = lhs_top.clone();
last.dst_type = rhs_top.clone();
if lhs_top != rhs_top {
let x = MorphismType {
bounds: Vec::new(),
src_type: lhs_top.clone(),
dst_type: rhs_top.clone()
}.strip_common_rungs();
let mut rl : Vec<_> = lhs_iter.cloned().collect();
rl.insert(0, x.src_type);
let mut rr : Vec<_> = rhs_iter.cloned().collect();
rr.insert(0, x.dst_type);
return MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Ladder(rl),
dst_type: TypeTerm::Ladder(rr)
};
}
}
last
}
(TypeTerm::Spec(args_lhs), TypeTerm::Spec(args_rhs)) => {
let (rl, rr) = args_lhs.iter().zip(args_rhs.iter()).map(
|(al,ar)| MorphismType{
bounds: Vec::new(),
src_type: al.clone(),
dst_type: ar.clone()
}.strip_common_rungs()
)
.fold((vec![], vec![]), |(mut rl, mut rr), x| {
rl.push(x.src_type);
rr.push(x.dst_type);
(rl,rr)
});
MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Spec(rl),
dst_type: TypeTerm::Spec(rr)
}
}
(TypeTerm::Seq { seq_repr:seq_repr_lhs, items:items_lhs },
TypeTerm::Seq { seq_repr: seq_repr_rhs, items:items_rhs })
=> {
let (rl, rr) = items_lhs.iter().zip(items_rhs.iter()).map(
|(al,ar)| MorphismType{
bounds: Vec::new(),
src_type: al.clone(),
dst_type: ar.clone()
}.strip_common_rungs()
)
.fold((vec![], vec![]), |(mut rl, mut rr), x| {
rl.push(x.src_type);
rr.push(x.dst_type);
(rl,rr)
});
MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Seq{ seq_repr: seq_repr_lhs.clone(), items: rl },
dst_type: TypeTerm::Seq { seq_repr: seq_repr_rhs.clone(), items: rr }
}
}
(TypeTerm::Struct { struct_repr:struct_repr_lhs, members:members_lhs },
TypeTerm::Struct { struct_repr: struct_repr_rhs, members:members_rhs })
=> {
let mut rl = Vec::new();
let mut rr = Vec::new();
for ar in members_rhs.iter() {
let mut found = false;
for al in members_lhs.iter() {
if al.symbol == ar.symbol {
let x = MorphismType{
bounds: Vec::new(),
src_type: al.ty.clone(),
dst_type: ar.ty.clone()
}.strip_common_rungs();
rl.push( StructMember{
symbol: al.symbol.clone(),
ty: x.src_type
});
rr.push( StructMember{
symbol: ar.symbol.clone(),
ty: x.dst_type
});
found = true;
break;
}
}
if !found {
return MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Struct { struct_repr: struct_repr_lhs.clone(), members:members_lhs.clone() },
dst_type: TypeTerm::Struct { struct_repr: struct_repr_rhs.clone(), members:members_rhs.clone() }
};
}
}
MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Struct{ struct_repr: struct_repr_lhs.clone(), members: rl },
dst_type: TypeTerm::Struct{ struct_repr: struct_repr_rhs.clone(), members: rr }
}
}
(TypeTerm::Enum { enum_repr:enum_repr_lhs, variants:variants_lhs },
TypeTerm::Enum { enum_repr: enum_repr_rhs, variants:variants_rhs })
=> {
let mut rl = Vec::new();
let mut rr = Vec::new();
for ar in variants_rhs.iter() {
let mut found = false;
for al in variants_lhs.iter() {
if al.symbol == ar.symbol {
let x = MorphismType {
bounds: self.bounds.clone(),
src_type: al.ty.clone(),
dst_type: ar.ty.clone()
}.strip_common_rungs();
rl.push( EnumVariant{
symbol: al.symbol.clone(),
ty: x.src_type
});
rr.push( EnumVariant{
symbol: ar.symbol.clone(),
ty: x.dst_type
});
found = true;
break;
}
}
if !found {
return MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Enum { enum_repr: enum_repr_lhs.clone(), variants:variants_lhs.clone() },
dst_type: TypeTerm::Enum { enum_repr: enum_repr_rhs.clone(), variants:variants_rhs.clone() }
};
}
}
MorphismType {
bounds: self.bounds.clone(),
src_type: TypeTerm::Enum{ enum_repr: enum_repr_lhs.clone(), variants: rl },
dst_type: TypeTerm::Enum { enum_repr: enum_repr_rhs.clone(), variants: rr }
}
}
(x,y) => MorphismType { bounds: self.bounds.clone(), src_type: x.clone(), dst_type: y.clone() }
}
}
pub fn apply_subst(&self, σ: &impl Substitution) -> MorphismType {
MorphismType {
bounds: self.bounds.iter().map(|b| b.clone().apply_subst(σ).clone()).collect(),
src_type: self.src_type.clone().apply_subst(σ).clone(),
dst_type: self.dst_type.clone().apply_subst(σ).clone()
}
}
pub fn normalize(&self) -> MorphismType {
MorphismType {
bounds: self.bounds.iter().map(|bound| bound.normalize()).collect(),
src_type: self.src_type.clone().normalize(),
dst_type: self.dst_type.clone().normalize(),
}
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\

View file

@ -3,7 +3,7 @@ use crate::{term::TypeTerm, constraint_system, EnumVariant, StructMember};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
pub fn splice_ladders( mut upper: Vec< TypeTerm >, mut lower: Vec< TypeTerm > ) -> Vec< TypeTerm > {
eprintln!("splice ladders {:?} <<<====>>> {:?} ", upper, lower);
//eprintln!("splice ladders {:?} <<<====>>> {:?} ", upper, lower);
// check for overlap
if lower.len() > 0 {
for i in 0 .. upper.len() {

View file

@ -9,8 +9,12 @@ use crate::{
#[test]
fn test_context() {
let root_ctx = Context::new();
/*
* Set up variable scopes
*/
let root_ctx = Context::new();
root_ctx.add_variable(
"DstRadix",
TypeKind::ValueUInt
@ -22,6 +26,12 @@ fn test_context() {
let mut sub2_ctx = root_ctx.scope();
assert_eq!( sub2_ctx.add_variable("SrcRadix", TypeKind::ValueUInt), 0 );
/*
* check variable IDs
*/
assert_eq!( sub1_ctx.get_typeid("Radix"), Some(TypeID::Var(0)) );
assert_eq!( sub1_ctx.get_typeid("DstRadix"), Some(TypeID::Var(1)) );
@ -30,22 +40,51 @@ fn test_context() {
assert_eq!( sub1_ctx.parse("Radix"), Ok(TypeTerm::Var(0)) );
/*
* assign variables in scoped context
*/
// Radix
sub1_ctx.bind(0, TypeTerm::Num(10));
// SrcRadix
sub2_ctx.bind(0, TypeTerm::Num(10));
// DstRadix
// Dst Radix
sub2_ctx.bind(1, TypeTerm::Num(16));
/*
* test that bound variables are substituted
*/
assert_eq!(
sub1_ctx
.parse("<PosInt Radix LittleEndian> ~ <Seq <Digit Radix>>").expect("parse error")
.apply_subst(&sub1_ctx).clone(),
sub1_ctx
.parse("<PosInt 10 LittleEndian> ~ <Seq <Digit 10>>").expect("parse error")
);
assert_eq!(
sub2_ctx
.parse("<PosInt SrcRadix LittleEndian>").expect("parse error")
.parse("<PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix>>").expect("parse error")
.apply_subst(&sub1_ctx).clone(),
sub2_ctx
.parse("<PosInt 10 LittleEndian>").expect("parse error")
.parse("<PosInt 10 LittleEndian> ~ <Seq <Digit 10>>").expect("parse error")
);
assert_eq!(
sub2_ctx
.parse("<PosInt DstRadix LittleEndian>").expect("parse error")
.apply_subst(&sub1_ctx).clone(),
sub2_ctx
.parse("<PosInt 16 LittleEndian>").expect("parse error")
);
}

View file

@ -1,4 +1,4 @@
use crate::{heuristic::*, dict::*, parser::*, morphism_graph::*};
use crate::{heuristic::*, dict::*, parser::*, morphism::*};
#[test]
fn test_heuristic() {

View file

@ -1,5 +1,5 @@
use {
crate::{dict::*, morphism_graph::*, parser::*,
crate::{dict::*, morphism::*, parser::*,
HashMapSubst, TypeTerm
},
std::collections::HashMap