more graph search tests, try to get substitutions correct
This commit is contained in:
parent
0a2d77a66f
commit
0d09c74e47
6 changed files with 338 additions and 351 deletions
|
@ -7,5 +7,8 @@ version = "0.1.0"
|
|||
[dependencies]
|
||||
tiny-ansi = { version = "0.1.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "*"
|
||||
|
||||
[features]
|
||||
pretty = ["dep:tiny-ansi"]
|
||||
|
|
|
@ -246,12 +246,11 @@ impl<M: Morphism + Clone> MorphismInstance<M> {
|
|||
TypeTerm::Ladder(vec![
|
||||
ψ.clone(),
|
||||
m.get_type().src_type
|
||||
]).normalize(),
|
||||
|
||||
]),
|
||||
dst_type: TypeTerm::Ladder(vec![
|
||||
ψ.clone(),
|
||||
m.get_type().dst_type
|
||||
]).normalize(),
|
||||
]),
|
||||
},
|
||||
MorphismInstance::Specialize { σ, m } =>
|
||||
MorphismType {
|
||||
|
@ -260,11 +259,11 @@ impl<M: Morphism + Clone> MorphismInstance<M> {
|
|||
},
|
||||
MorphismInstance::Chain { path } => {
|
||||
if path.len() > 0 {
|
||||
let s = self.get_subst();
|
||||
//let s = self.get_subst();
|
||||
MorphismType {
|
||||
src_type: path.first().unwrap().get_type().src_type.clone(),
|
||||
dst_type: path.last().unwrap().get_type().dst_type.clone()
|
||||
}.apply_subst(&s)
|
||||
}//.apply_subst(&s)
|
||||
} else {
|
||||
MorphismType {
|
||||
src_type: TypeTerm::TypeID(TypeID::Fun(45454)),
|
||||
|
|
|
@ -2,7 +2,7 @@ use {
|
|||
crate::{
|
||||
//morphism_path::{MorphismPath, ShortestPathProblem},
|
||||
morphism::{Morphism, MorphismInstance, MorphismType}, StructMember, TypeDict, TypeID, TypeTerm
|
||||
}, std::{char::decode_utf16, io::{Read, Write}}
|
||||
}, std::{char::decode_utf16, collections::HashMap, io::{Read, Write}}
|
||||
};
|
||||
|
||||
pub trait MorphBase<
|
||||
|
@ -18,7 +18,7 @@ pub trait MorphBase<
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum DecomposedMorphismType {
|
||||
SeqMap { item: MorphismType },
|
||||
StructMap { members: Vec<(String, MorphismType)> },
|
||||
|
@ -62,7 +62,6 @@ impl<M: Morphism + Clone> MorphismBase<M> {
|
|||
}
|
||||
}
|
||||
|
||||
eprintln!("Attempt Complex Decomposition....");
|
||||
match (src_floor, dst_floor) {
|
||||
(TypeTerm::Struct{ struct_repr: struct_repr_lhs, members: members_lhs},
|
||||
TypeTerm::Struct { struct_repr: struct_repr_rhs, members: members_rhs })
|
||||
|
@ -126,7 +125,7 @@ impl<M: Morphism + Clone> MorphismBase<M> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn enum_morphisms_from(&self, src_type: &TypeTerm) -> Vec< MorphismInstance<M> > {
|
||||
pub fn enum_morphisms_from(&self, src_type: &TypeTerm) -> Vec< (TypeTerm, HashMap<TypeID, TypeTerm>, M) > {
|
||||
let mut morphs = Vec::new();
|
||||
|
||||
for m in self.morphisms.iter() {
|
||||
|
@ -139,18 +138,7 @@ impl<M: Morphism + Clone> MorphismBase<M> {
|
|||
// morphisms source type,
|
||||
// i.e. check if `src_type` is a subtype of `m_src_type`
|
||||
if let Ok((ψ, σ)) = crate::constraint_system::subtype_unify(src_type, &m_src_type) {
|
||||
let mut m = MorphismInstance::Primitive { m: m.clone() };
|
||||
|
||||
if !σ.is_empty() {
|
||||
m = MorphismInstance::Specialize { σ, m: Box::new(m) };
|
||||
}
|
||||
|
||||
if !ψ.is_empty() {
|
||||
m = MorphismInstance::Sub { ψ, m: Box::new(m) }
|
||||
}
|
||||
|
||||
eprintln!("..found direct morph to {:?}", m.get_type().dst_type);
|
||||
morphs.push(m);
|
||||
morphs.push((ψ, σ, m.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,53 +152,11 @@ impl<M: Morphism + Clone> MorphismBase<M> {
|
|||
|
||||
/* 2. check complex types */
|
||||
if let Some(decomposition) = self.morphism_decomposition(src_type, &m_src_type) {
|
||||
eprintln!("found complex morph to {:?}", decomposition);
|
||||
morphs.push(decomposition);
|
||||
}
|
||||
}
|
||||
morphs
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn to_dot(&self, dict: &mut impl TypeDict) -> String {
|
||||
let mut dot_source = String::new();
|
||||
|
||||
dot_source.push_str("digraph MorphismGraph {");
|
||||
|
||||
pub fn ty_to_dot_label(dict: &mut impl TypeDict, ty: &TypeTerm) -> String {
|
||||
let pretty_str = ty.pretty(dict, 0);
|
||||
let mut child = std::process::Command::new("aha").arg("--no-header")
|
||||
.stdin( std::process::Stdio::piped() )
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.spawn().expect("spawn child");
|
||||
let mut stdin = child.stdin.take().expect("cant get stdin");
|
||||
std::thread::spawn(move ||{ stdin.write_all(pretty_str.as_bytes()).expect("failed to write")});
|
||||
let out = child.wait_with_output().expect("");
|
||||
let html_str = String::from_utf8_lossy(&out.stdout).replace("\n", "<BR/>").replace("span", "B");
|
||||
html_str
|
||||
}
|
||||
|
||||
// add vertices
|
||||
for (i,m) in self.morphisms.iter().enumerate() {
|
||||
dot_source.push_str(&format!("
|
||||
SRC{} [label=<{}>]
|
||||
DST{} [label=<{}>]
|
||||
|
||||
SRC{} -> DST{} [label=\"{}\"]
|
||||
", i, ty_to_dot_label(dict, &m.get_type().src_type),
|
||||
i, ty_to_dot_label(dict, &m.get_type().dst_type),
|
||||
i,i,i
|
||||
));
|
||||
}
|
||||
|
||||
// add edges
|
||||
|
||||
|
||||
dot_source.push_str("}");
|
||||
|
||||
dot_source
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
||||
|
|
|
@ -8,19 +8,22 @@ use {
|
|||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
||||
|
||||
pub struct MorphismGraph<M: Morphism+Clone> {
|
||||
pub struct MorphismGraph<M: Morphism+Clone+std::fmt::Debug> {
|
||||
solved_paths: HashMap< MorphismType, MorphismInstance<M> >,
|
||||
base: MorphismBase<M>
|
||||
}
|
||||
|
||||
pub struct GraphSearch<M: Morphism+Clone> {
|
||||
#[derive(Debug)]
|
||||
pub struct GraphSearch<M: Morphism+Clone+std::fmt::Debug> {
|
||||
goal: MorphismType,
|
||||
solution: Option< MorphismInstance<M> >,
|
||||
explore_queue: Vec< Arc<RwLock<SearchNode<M>>> >
|
||||
explore_queue: Vec< Arc<RwLock<SearchNode<M>>> >,
|
||||
|
||||
skip_preview: bool
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum GraphSearchState<M: Morphism+Clone> {
|
||||
pub enum GraphSearchState<M: Morphism+Clone+std::fmt::Debug> {
|
||||
Solved( MorphismInstance<M> ),
|
||||
Continue,
|
||||
Err( GraphSearchError )
|
||||
|
@ -34,19 +37,23 @@ pub enum GraphSearchError {
|
|||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
||||
|
||||
/// represents a partial path during search in the morphism graph
|
||||
pub struct SearchNode<M: Morphism+Clone> {
|
||||
#[derive(Debug)]
|
||||
pub struct SearchNode<M: Morphism+Clone+std::fmt::Debug> {
|
||||
/// predecessor node
|
||||
pred: Option< Arc<RwLock< SearchNode<M> >> >,
|
||||
|
||||
/// (measured) weight of the preceding path
|
||||
weight: u64,
|
||||
|
||||
ty: MorphismType,
|
||||
|
||||
/// the advancement over pred
|
||||
step: Step<M>,
|
||||
ψ: TypeTerm,
|
||||
}
|
||||
|
||||
pub enum Step<M: Morphism+Clone> {
|
||||
#[derive(Debug)]
|
||||
pub enum Step<M: Morphism+Clone+std::fmt::Debug> {
|
||||
Id { τ: TypeTerm },
|
||||
Inst{ m: MorphismInstance<M> },
|
||||
Specialize { σ: HashMap<TypeID, TypeTerm> },
|
||||
|
@ -55,29 +62,43 @@ pub enum Step<M: Morphism+Clone> {
|
|||
MapEnum { variants: Vec< (String, GraphSearch<M>) > }
|
||||
}
|
||||
|
||||
impl<M:Morphism+Clone> SearchNode<M> {
|
||||
|
||||
}
|
||||
|
||||
pub trait SearchNodeExt<M: Morphism+Clone> {
|
||||
pub trait SearchNodeExt<M: Morphism+Clone+std::fmt::Debug> {
|
||||
fn specialize(&self, σ: HashMap<TypeID, TypeTerm>) -> Arc<RwLock<SearchNode<M>>>;
|
||||
fn chain(&self, m: &MorphismInstance<M>) -> Arc<RwLock<SearchNode<M>>>;
|
||||
fn chain(&self, ψ: TypeTerm, σ: HashMap<TypeID, TypeTerm>, m: M) -> Arc<RwLock<SearchNode<M>>>;
|
||||
fn set_sub(&self, ψ: TypeTerm) -> Arc<RwLock<SearchNode<M>>>;
|
||||
fn map_seq(&self, goal: MorphismType) -> Arc<RwLock<SearchNode<M>>>;
|
||||
fn map_struct(&self, goals: Vec<(String, MorphismType)>) -> Arc<RwLock<SearchNode<M>>>;
|
||||
fn map_enum(&self, goals: Vec<(String, MorphismType)>) -> Arc<RwLock<SearchNode<M>>>;
|
||||
fn to_morphism_instance(&self) -> Option< MorphismInstance<M> >;
|
||||
fn get_type(&self) -> MorphismType;
|
||||
|
||||
fn advance(&self, base: &MorphismBase<M>, dict: &mut impl TypeDict) -> Result<bool, GraphSearchError>;
|
||||
fn to_morphism_instance(&self) -> Option< MorphismInstance<M> >;
|
||||
|
||||
fn is_ready(&self) -> bool;
|
||||
fn get_weight(&self) -> u64;
|
||||
fn get_type(&self) -> MorphismType;
|
||||
|
||||
fn creates_loop(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
||||
impl<M: Morphism+Clone+std::fmt::Debug> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
||||
fn get_weight(&self) -> u64 {
|
||||
self.read().unwrap().weight
|
||||
+ match &self.read().unwrap().step {
|
||||
Step::Id { τ } => 0,
|
||||
Step::Inst { m } => m.get_weight(),
|
||||
Step::Specialize { σ } => 0,
|
||||
Step::MapSeq { item } => item.best_path_weight(),
|
||||
Step::MapStruct { members } => todo!(),
|
||||
Step::MapEnum { variants } => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_type(&self) -> MorphismType {
|
||||
let s = self.read().unwrap();
|
||||
MorphismType {
|
||||
src_type: TypeTerm::Ladder(vec![ s.ψ.clone(), s.ty.src_type.clone() ]).normalize(),
|
||||
dst_type: TypeTerm::Ladder(vec![ s.ψ.clone(), s.ty.dst_type.clone() ]).normalize(),
|
||||
}
|
||||
}
|
||||
fn is_ready(&self) -> bool {
|
||||
let n = self.read().unwrap();
|
||||
|
@ -99,6 +120,21 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
|||
}
|
||||
}
|
||||
|
||||
fn creates_loop(&self) -> bool {
|
||||
/*
|
||||
let mut cur_node = self.read().unwrap().pred.clone();
|
||||
while let Some(n) = cur_node {
|
||||
if n.get_type().dst_type == self.get_type().dst_type {
|
||||
return true;
|
||||
}
|
||||
|
||||
cur_node = n.read().unwrap().pred.clone();
|
||||
}
|
||||
*/
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn advance(&self, base: &MorphismBase<M>, dict: &mut impl TypeDict) -> Result<bool, GraphSearchError> {
|
||||
let mut n = self.write().unwrap();
|
||||
match &mut n.step {
|
||||
|
@ -106,20 +142,15 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
|||
eprintln!("advance seq-map");
|
||||
match item.advance(base, dict) {
|
||||
GraphSearchState::Solved(item_morph) => {
|
||||
|
||||
let map_morph = MorphismInstance::MapSeq {
|
||||
seq_repr: None,
|
||||
item_morph: Box::new(item_morph)
|
||||
eprintln!("Sequence-Map Sub Graph Solved!!");
|
||||
n.ty = MorphismType {
|
||||
src_type: TypeTerm::Seq { seq_repr: None, items: vec![ item_morph.get_type().src_type ] },
|
||||
dst_type: TypeTerm::Seq { seq_repr: None, items: vec![ item_morph.get_type().dst_type ] },
|
||||
};
|
||||
return Ok(false);
|
||||
}
|
||||
GraphSearchState::Err(err) => {
|
||||
return Err(err)
|
||||
},
|
||||
GraphSearchState::Continue => {
|
||||
//self.explore_queue.push(node.clone());
|
||||
return Ok(true);
|
||||
Ok(false)
|
||||
}
|
||||
GraphSearchState::Continue => Ok(true),
|
||||
GraphSearchState::Err(err) => Err(err)
|
||||
}
|
||||
}
|
||||
Step::MapStruct { members } => {
|
||||
|
@ -128,52 +159,59 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
|||
Step::MapEnum { variants } => {
|
||||
todo!()
|
||||
}
|
||||
/*
|
||||
Step::Sub { ψ } =>{
|
||||
return n.pred.as_ref().unwrap().advance(base, dict);
|
||||
}
|
||||
*/
|
||||
|
||||
_ => {}
|
||||
_ => Ok(false)
|
||||
}
|
||||
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
fn specialize(&self, σ: HashMap<TypeID, TypeTerm>) -> Arc<RwLock<SearchNode<M>>> {
|
||||
Arc::new(RwLock::new(SearchNode {
|
||||
pred: Some(self.clone()),
|
||||
weight: self.read().unwrap().weight,
|
||||
weight: self.get_weight(),
|
||||
ty: MorphismType {
|
||||
src_type: self.get_type().src_type.apply_subst(&σ).clone().normalize(),
|
||||
dst_type: self.get_type().dst_type.apply_subst(&σ).clone().normalize()
|
||||
},
|
||||
step: Step::Specialize { σ },
|
||||
ψ: self.read().unwrap().ψ.clone()
|
||||
}))
|
||||
}
|
||||
|
||||
fn chain(&self, m: &MorphismInstance<M>) -> Arc<RwLock<SearchNode<M>>> {
|
||||
Arc::new(RwLock::new(SearchNode {
|
||||
fn chain(&self, ψ: TypeTerm, σ: HashMap<TypeID, TypeTerm>, m: M) -> Arc<RwLock<SearchNode<M>>> {
|
||||
let m = MorphismInstance::Primitive { m: m.clone() };
|
||||
|
||||
let mut n = Arc::new(RwLock::new(SearchNode {
|
||||
pred: Some(self.clone()),
|
||||
weight: self.read().unwrap().weight + m.get_weight(),
|
||||
step: Step::Inst{ m: m.clone() },
|
||||
ψ: self.read().unwrap().ψ.clone()
|
||||
}))
|
||||
weight: self.get_weight(),
|
||||
ty: MorphismType {
|
||||
src_type: self.get_type().src_type,
|
||||
dst_type: m.get_type().dst_type
|
||||
},
|
||||
step: Step::Inst{ m },
|
||||
ψ: TypeTerm::unit(),//self.read().unwrap().ψ.clone()
|
||||
}));
|
||||
n.set_sub(ψ);
|
||||
|
||||
if !σ.is_empty() {
|
||||
n = n.specialize(σ);
|
||||
}
|
||||
|
||||
n
|
||||
}
|
||||
|
||||
fn set_sub(&self, ψ: TypeTerm) -> Arc<RwLock<SearchNode<M>>> {
|
||||
self.write().unwrap().ψ = ψ;
|
||||
let oldψ = &mut self.write().unwrap().ψ;
|
||||
*oldψ = TypeTerm::Ladder(vec![ ψ, oldψ.clone() ]).normalize();
|
||||
self.clone()
|
||||
/*
|
||||
Arc::new(RwLock::new(SearchNode {
|
||||
pred: Some(self.clone()),
|
||||
weight: self.read().unwrap().weight,
|
||||
step: Step::Sub{ ψ }
|
||||
}))
|
||||
*/
|
||||
}
|
||||
|
||||
fn map_seq(&self, goal: MorphismType) -> Arc<RwLock<SearchNode<M>>> {
|
||||
Arc::new(RwLock::new(SearchNode {
|
||||
pred: Some(self.clone()),
|
||||
weight: self.read().unwrap().weight,
|
||||
weight: self.get_weight(),
|
||||
ty: MorphismType {
|
||||
src_type: TypeTerm::Seq{ seq_repr: None, items: vec![goal.src_type.clone()] },
|
||||
dst_type: TypeTerm::Seq{ seq_repr: None, items: vec![goal.src_type.clone()] }
|
||||
},
|
||||
step: Step::MapSeq { item: GraphSearch::new(goal) },
|
||||
ψ: self.read().unwrap().ψ.clone()
|
||||
}))
|
||||
|
@ -182,7 +220,8 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
|||
fn map_struct(&self, goals: Vec<(String, MorphismType)>) -> Arc<RwLock<SearchNode<M>>> {
|
||||
Arc::new(RwLock::new(SearchNode {
|
||||
pred: Some(self.clone()),
|
||||
weight: self.read().unwrap().weight,
|
||||
weight: self.get_weight(),
|
||||
ty: todo!(),
|
||||
step: Step::MapStruct { members: goals.into_iter().map(|(name,goal)| (name, GraphSearch::new(goal))).collect() },
|
||||
ψ: self.read().unwrap().ψ.clone()
|
||||
}))
|
||||
|
@ -191,7 +230,8 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
|||
fn map_enum(&self, goals: Vec<(String, MorphismType)>) -> Arc<RwLock<SearchNode<M>>> {
|
||||
Arc::new(RwLock::new(SearchNode {
|
||||
pred: Some(self.clone()),
|
||||
weight: self.read().unwrap().weight,
|
||||
weight: self.get_weight(),
|
||||
ty: todo!(),
|
||||
step: Step::MapEnum { variants: goals.into_iter().map(|(name,goal)| (name, GraphSearch::new(goal))).collect() },
|
||||
ψ: self.read().unwrap().ψ.clone()
|
||||
}))
|
||||
|
@ -202,21 +242,25 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
|||
let mut path = Vec::new();
|
||||
let mut subst = HashMap::new();
|
||||
|
||||
// let mut halos = Vec::new();
|
||||
|
||||
let mut cur_node = Some(self.clone());
|
||||
while let Some(n) = cur_node {
|
||||
let n = n.read().unwrap();
|
||||
match &n.step {
|
||||
Step::Id { τ } => { begin = τ.clone(); },
|
||||
Step::Inst{ m } => {
|
||||
let mut m = m.clone();
|
||||
let σ = subst.clone().filter_morphtype(&m.get_type());
|
||||
/*
|
||||
if !σ.is_empty() {
|
||||
m = MorphismInstance::Specialize { σ, m: Box::new(m) }
|
||||
}
|
||||
*/
|
||||
if ! n.ψ.is_empty() {
|
||||
m = MorphismInstance::Sub { ψ: n.ψ.clone(), m: Box::new(m) };
|
||||
}
|
||||
|
||||
path.push(m.clone());
|
||||
},
|
||||
/*
|
||||
Step::Sub { ψ } => {
|
||||
halos.push(ψ.clone());
|
||||
}
|
||||
*/
|
||||
Step::Specialize { σ } => {
|
||||
subst = subst.append(&σ);
|
||||
}
|
||||
|
@ -230,6 +274,13 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
|||
m = MorphismInstance::Sub { ψ: n.ψ.clone(), m: Box::new(m) };
|
||||
}
|
||||
|
||||
/*
|
||||
let σ = subst.clone().filter_morphtype(&m.get_type());
|
||||
if !σ.is_empty() {
|
||||
m = MorphismInstance::Specialize { σ, m: Box::new(m) }
|
||||
}
|
||||
*/
|
||||
|
||||
path.push(m);
|
||||
}
|
||||
Step::MapStruct { members } => {
|
||||
|
@ -246,6 +297,13 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
|||
|
||||
path.reverse();
|
||||
|
||||
for m in path.iter_mut() {
|
||||
let σ = subst.clone().filter_morphtype(&m.get_type());
|
||||
if !σ.is_empty() {
|
||||
*m = MorphismInstance::Specialize { σ, m: Box::new(m.clone()) };
|
||||
}
|
||||
}
|
||||
|
||||
let mut m =
|
||||
if path.len() == 0 {
|
||||
MorphismInstance::Id { τ: begin }
|
||||
|
@ -255,9 +313,6 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
|||
MorphismInstance::Chain { path }
|
||||
};
|
||||
|
||||
|
||||
eprintln!("to_morph_instance() σ = {:?}", subst);
|
||||
|
||||
subst = subst.filter_morphtype(&m.get_type());
|
||||
if !subst.is_empty() {
|
||||
m = MorphismInstance::Specialize { σ: subst, m: Box::new(m) };
|
||||
|
@ -265,64 +320,11 @@ impl<M: Morphism+Clone> SearchNodeExt<M> for Arc<RwLock<SearchNode<M>>> {
|
|||
|
||||
Some(m)
|
||||
}
|
||||
|
||||
fn get_type(&self) -> MorphismType {
|
||||
let s = self.read().unwrap();
|
||||
let t = match &s.step {
|
||||
Step::Id { τ } => MorphismType {
|
||||
src_type: τ.clone(),
|
||||
dst_type: τ.clone()
|
||||
},
|
||||
/*
|
||||
Step::Sub { ψ } => {
|
||||
MorphismType {
|
||||
src_type: TypeTerm::Ladder(vec![
|
||||
ψ.clone(),
|
||||
s.pred.as_ref().unwrap().get_type().src_type
|
||||
]),
|
||||
dst_type: TypeTerm::Ladder(vec![
|
||||
ψ.clone(),
|
||||
s.pred.as_ref().unwrap().get_type().dst_type
|
||||
])
|
||||
}
|
||||
}
|
||||
*/
|
||||
Step::Inst{ m } => {
|
||||
MorphismType {
|
||||
src_type: s.pred.as_ref().unwrap().get_type().src_type,
|
||||
dst_type: m.get_type().dst_type
|
||||
}
|
||||
},
|
||||
Step::Specialize { σ } => {
|
||||
if let Some(p) = s.pred.as_ref() {
|
||||
MorphismType {
|
||||
src_type: p.get_type().src_type.apply_subst(σ).clone().normalize(),
|
||||
dst_type: p.get_type().dst_type.apply_subst(σ).clone().normalize()
|
||||
}
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
},
|
||||
Step::MapSeq { item } => {
|
||||
MorphismType {
|
||||
src_type: TypeTerm::Seq{ seq_repr: None, items: vec![item.goal.src_type.clone()] },
|
||||
dst_type: TypeTerm::Seq{ seq_repr: None, items: vec![item.goal.dst_type.clone()] }
|
||||
}
|
||||
}
|
||||
|
||||
_ => todo!()
|
||||
};
|
||||
|
||||
MorphismType {
|
||||
src_type: TypeTerm::Ladder(vec![ s.ψ.clone(), t.src_type ]).normalize(),
|
||||
dst_type: TypeTerm::Ladder(vec![ s.ψ.clone(), t.dst_type ]).normalize(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
||||
|
||||
impl<M: Morphism+Clone> MorphismGraph<M> {
|
||||
impl<M: Morphism+Clone+std::fmt::Debug> MorphismGraph<M> {
|
||||
pub fn new(base: MorphismBase<M>) -> Self {
|
||||
MorphismGraph {
|
||||
solved_paths: HashMap::new(),
|
||||
|
@ -336,7 +338,6 @@ impl<M: Morphism+Clone> MorphismGraph<M> {
|
|||
> {
|
||||
let mut search = GraphSearch::<M>::new(goal);
|
||||
loop {
|
||||
eprintln!("try to advance search..");
|
||||
match search.advance(&self.base, dict) {
|
||||
GraphSearchState::Solved(m) => { return Ok(m); }
|
||||
GraphSearchState::Continue => { continue; }
|
||||
|
@ -346,9 +347,8 @@ impl<M: Morphism+Clone> MorphismGraph<M> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<M: Morphism+Clone> GraphSearch<M> {
|
||||
impl<M: Morphism+Clone+std::fmt::Debug> GraphSearch<M> {
|
||||
pub fn new(goal: MorphismType) -> Self {
|
||||
eprintln!("New GraphSearch Problem!");
|
||||
GraphSearch {
|
||||
goal: goal.clone(),
|
||||
solution: None,
|
||||
|
@ -356,10 +356,15 @@ impl<M: Morphism+Clone> GraphSearch<M> {
|
|||
Arc::new(RwLock::new(SearchNode {
|
||||
pred: None,
|
||||
weight: 0,
|
||||
ty: MorphismType {
|
||||
src_type: goal.src_type.clone(),
|
||||
dst_type: goal.src_type.clone()
|
||||
},
|
||||
step: Step::Id { τ: goal.src_type.clone() },
|
||||
ψ: TypeTerm::unit()
|
||||
}))
|
||||
]
|
||||
],
|
||||
skip_preview: false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,6 +372,14 @@ impl<M: Morphism+Clone> GraphSearch<M> {
|
|||
self.solution.clone()
|
||||
}
|
||||
|
||||
pub fn best_path_weight(&self) -> u64 {
|
||||
if let Some(best) = self.explore_queue.last() {
|
||||
best.get_weight()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn est_remain(goal: &MorphismType, search_node: &Arc<RwLock<SearchNode<M>>>) -> u64 {
|
||||
MorphismType {
|
||||
src_type: goal.src_type.clone(),
|
||||
|
@ -389,20 +402,24 @@ impl<M: Morphism+Clone> GraphSearch<M> {
|
|||
)
|
||||
}
|
||||
);
|
||||
|
||||
eprintln!("===== TOP 5 PATHS =====\nGoal:\n {} -> {}",
|
||||
goal.src_type.pretty(dict, 0),
|
||||
goal.dst_type.pretty(dict, 0)
|
||||
);
|
||||
for i in 1 ..= usize::min(self.explore_queue.len(), 5) {
|
||||
let n = &self.explore_queue[self.explore_queue.len() - i];
|
||||
eprintln!("[[ {} ]] (weight: {} + est remain: {}) --- {} --> {}", i,
|
||||
n.get_weight(),
|
||||
Self::est_remain(&goal, &n),
|
||||
n.get_type().src_type.pretty(dict, 0),
|
||||
n.get_type().dst_type.pretty(dict, 0));
|
||||
/*
|
||||
if !self.skip_preview {
|
||||
eprintln!("===== TOP 5 PATHS =====\nGoal:\n {} -> {}",
|
||||
goal.src_type.pretty(dict, 0),
|
||||
goal.dst_type.pretty(dict, 0)
|
||||
);
|
||||
for i in 1 ..= usize::min(self.explore_queue.len(), 5) {
|
||||
let n = &self.explore_queue[self.explore_queue.len() - i];
|
||||
eprintln!("[[ {} ]] (weight: {} + est remain: {}) --- {} --> {}", i,
|
||||
n.get_weight(),
|
||||
Self::est_remain(&goal, &n),
|
||||
n.get_type().src_type.pretty(dict, 0),
|
||||
n.get_type().dst_type.pretty(dict, 0));
|
||||
}
|
||||
} else {
|
||||
self.skip_preview = false;
|
||||
}
|
||||
|
||||
*/
|
||||
self.explore_queue.pop()
|
||||
}
|
||||
|
||||
|
@ -411,7 +428,10 @@ impl<M: Morphism+Clone> GraphSearch<M> {
|
|||
match node.advance(base, dict) {
|
||||
Ok(_) => {
|
||||
if ! node.is_ready() {
|
||||
self.explore_queue.push(node);
|
||||
if ! node.creates_loop() {
|
||||
self.skip_preview = true;
|
||||
self.explore_queue.push(node);
|
||||
}
|
||||
return GraphSearchState::Continue;
|
||||
} else {
|
||||
let w = node.to_morphism_instance().unwrap().get_weight();
|
||||
|
@ -424,6 +444,10 @@ impl<M: Morphism+Clone> GraphSearch<M> {
|
|||
}
|
||||
}
|
||||
|
||||
if node.creates_loop() {
|
||||
return GraphSearchState::Continue;
|
||||
}
|
||||
|
||||
/* 1. Check if goal is already reached by the current path */
|
||||
if let Ok((_ψ, σ)) = crate::constraint_system::subtype_unify( &node.get_type().dst_type, &self.goal.dst_type ) {
|
||||
/* found path */
|
||||
|
@ -431,39 +455,43 @@ impl<M: Morphism+Clone> GraphSearch<M> {
|
|||
if σ.is_empty() {
|
||||
node.to_morphism_instance().unwrap()
|
||||
} else {
|
||||
node.specialize( σ.filter_morphtype(&node.get_type()) ).to_morphism_instance().unwrap()
|
||||
node
|
||||
.specialize( σ.filter_morphtype(&node.get_type()) )
|
||||
.to_morphism_instance()
|
||||
.unwrap()
|
||||
}
|
||||
);
|
||||
|
||||
return GraphSearchState::Solved(self.get_solution().unwrap());
|
||||
}
|
||||
else if let Some((ψ, decomposition)) = base.morphism_decomposition(&node.get_type().dst_type, &self.goal.dst_type) {
|
||||
self.explore_queue.push(
|
||||
match decomposition {
|
||||
DecomposedMorphismType::SeqMap { item } => { node.map_seq( item ) },
|
||||
DecomposedMorphismType::StructMap { members } => { node.map_struct(members) },
|
||||
DecomposedMorphismType::EnumMap { variants } => { node.map_enum(variants) },
|
||||
}.set_sub(ψ.clone())
|
||||
);
|
||||
//return GraphSearchState::Continue;
|
||||
|
||||
let mut decompositions = base.enum_complex_morphisms(&node.get_type().dst_type);
|
||||
if let Some(d) = base.morphism_decomposition(&node.get_type().dst_type, &self.goal.dst_type) {
|
||||
decompositions.push(d);
|
||||
}
|
||||
|
||||
//eprintln!("{} decompositions", decompositions.len());
|
||||
|
||||
let mut done = Vec::new();
|
||||
for (ψ,decomposition) in decompositions {
|
||||
if ! done.contains(&(ψ.clone(),decomposition.clone())) {
|
||||
self.explore_queue.push(
|
||||
match &decomposition {
|
||||
DecomposedMorphismType::SeqMap { item } => { node.map_seq( item.clone() ) },
|
||||
DecomposedMorphismType::StructMap { members } => { node.map_struct(members.clone()) },
|
||||
DecomposedMorphismType::EnumMap { variants } => { node.map_enum(variants.clone()) },
|
||||
}.set_sub(ψ.clone())
|
||||
);
|
||||
done.push((ψ, decomposition));
|
||||
}else {
|
||||
//eprintln!("avoid duplicate decomposition");
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. Try to advance current path */
|
||||
for next_morph_inst in base.enum_morphisms_from(&node.get_type().dst_type) {
|
||||
eprintln!("add direct path");
|
||||
self.explore_queue.push( node.chain(&next_morph_inst) );
|
||||
}
|
||||
|
||||
eprintln!("check complex decompositions from {}", node.get_type().dst_type.pretty(dict,0));
|
||||
for (ψ,decomposition) in base.enum_complex_morphisms(&node.get_type().dst_type) {
|
||||
eprintln!("add decomposition!");
|
||||
self.explore_queue.push(
|
||||
match decomposition {
|
||||
DecomposedMorphismType::SeqMap { item } => { node.map_seq( item ) },
|
||||
DecomposedMorphismType::StructMap { members } => { node.map_struct(members) },
|
||||
DecomposedMorphismType::EnumMap { variants } => { node.map_enum(variants) },
|
||||
}.set_sub(ψ)
|
||||
);
|
||||
for (ψ,σ,m) in base.enum_morphisms_from(&node.get_type().dst_type) {
|
||||
//eprintln!("add direct path");
|
||||
self.explore_queue.push( node.chain(ψ,σ,m) );
|
||||
}
|
||||
|
||||
GraphSearchState::Continue
|
||||
|
|
20
src/pnf.rs
20
src/pnf.rs
|
@ -5,17 +5,19 @@ 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);
|
||||
// check for overlap
|
||||
for i in 0 .. upper.len() {
|
||||
if upper[i] == lower[0] {
|
||||
let mut result_ladder = Vec::<TypeTerm>::new();
|
||||
result_ladder.append(&mut upper[0..i].iter().cloned().collect());
|
||||
result_ladder.append(&mut lower);
|
||||
return result_ladder;
|
||||
if lower.len() > 0 {
|
||||
for i in 0 .. upper.len() {
|
||||
if upper[i] == lower[0] {
|
||||
let mut result_ladder = Vec::<TypeTerm>::new();
|
||||
result_ladder.append(&mut upper[0..i].iter().cloned().collect());
|
||||
result_ladder.append(&mut lower);
|
||||
return result_ladder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no overlap found, just concatenate ladders
|
||||
upper.append(&mut lower);
|
||||
// no overlap found, just concatenate ladders
|
||||
upper.append(&mut lower);
|
||||
}
|
||||
upper
|
||||
}
|
||||
|
||||
|
|
|
@ -8,34 +8,8 @@ use {
|
|||
std::collections::HashMap
|
||||
};
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
||||
|
||||
fn print_subst(m: &std::collections::HashMap<TypeID, TypeTerm>, dict: &mut impl TypeDict) {
|
||||
eprintln!("{{");
|
||||
|
||||
for (k,v) in m.iter() {
|
||||
eprintln!(" {} --> {}",
|
||||
dict.get_typename(k).unwrap(),
|
||||
v.pretty(dict, 0)
|
||||
);
|
||||
}
|
||||
|
||||
eprintln!("}}");
|
||||
}
|
||||
|
||||
fn print_path(dict: &mut impl TypeDict, path: &Vec<MorphismInstance<DummyMorphism>>) {
|
||||
for n in path.iter() {
|
||||
eprintln!("
|
||||
morph {}
|
||||
--> {}
|
||||
with
|
||||
",
|
||||
n.get_type().src_type.pretty(dict, 0),
|
||||
n.get_type().dst_type.pretty(dict, 0),
|
||||
);
|
||||
print_subst(&n.get_subst(), dict)
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
use pretty_assertions::{assert_eq, assert_ne};
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
|
||||
|
||||
|
@ -57,46 +31,47 @@ fn morphism_test_setup() -> ( BimapTypeDict, MorphismBase<DummyMorphism> ) {
|
|||
|
||||
base.add_morphism(
|
||||
DummyMorphism(MorphismType{
|
||||
src_type: dict.parse_desugared("<Digit Radix> ~ Char").unwrap().sugar(&mut dict),
|
||||
dst_type: dict.parse_desugared("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict)
|
||||
src_type: dict.parse("<Digit Radix> ~ Char").unwrap(),
|
||||
dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap()
|
||||
})
|
||||
);
|
||||
base.add_morphism(
|
||||
DummyMorphism(MorphismType{
|
||||
src_type: dict.parse_desugared("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict),
|
||||
dst_type: dict.parse_desugared("<Digit Radix> ~ Char").unwrap().sugar(&mut dict)
|
||||
src_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap(),
|
||||
dst_type: dict.parse("<Digit Radix> ~ Char").unwrap()
|
||||
})
|
||||
);
|
||||
|
||||
base.add_morphism(
|
||||
DummyMorphism(MorphismType{
|
||||
src_type: dict.parse_desugared("ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict),
|
||||
dst_type: dict.parse_desugared("ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict)
|
||||
src_type: dict.parse("ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap(),
|
||||
dst_type: dict.parse("ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap()
|
||||
})
|
||||
);
|
||||
base.add_morphism(
|
||||
DummyMorphism(MorphismType{
|
||||
src_type: dict.parse_desugared("ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict),
|
||||
dst_type: dict.parse_desugared("ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict)
|
||||
})
|
||||
);
|
||||
base.add_morphism(
|
||||
DummyMorphism(MorphismType{
|
||||
src_type: dict.parse_desugared("ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict),
|
||||
dst_type: dict.parse_desugared("ℕ ~ <PosInt DstRadix LittleEndian> ~ <Seq <Digit DstRadix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict)
|
||||
src_type: dict.parse("ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap(),
|
||||
dst_type: dict.parse("ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap()
|
||||
})
|
||||
);
|
||||
|
||||
base.add_morphism(
|
||||
DummyMorphism(MorphismType{
|
||||
src_type: dict.parse_desugared("ℤ_2^64 ~ ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict),
|
||||
dst_type: dict.parse_desugared("ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict)
|
||||
src_type: dict.parse("ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>").unwrap(),
|
||||
dst_type: dict.parse("ℕ ~ <PosInt DstRadix LittleEndian> ~ <Seq <Digit DstRadix>~ℤ_2^64~machine.UInt64>").unwrap()
|
||||
})
|
||||
);
|
||||
|
||||
base.add_morphism(
|
||||
DummyMorphism(MorphismType{
|
||||
src_type: dict.parse("ℤ_2^64 ~ ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>").unwrap(),
|
||||
dst_type: dict.parse("ℤ_2^64 ~ machine.UInt64").unwrap()
|
||||
})
|
||||
);
|
||||
base.add_morphism(
|
||||
DummyMorphism(MorphismType{
|
||||
src_type: dict.parse_desugared("ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict),
|
||||
dst_type: dict.parse_desugared("ℤ_2^64 ~ ℕ ~ <PosInt 0 LittleEndian> ~ <Seq <Digit 0>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict)
|
||||
src_type: dict.parse("ℤ_2^64 ~ machine.UInt64").unwrap(),
|
||||
dst_type: dict.parse("ℤ_2^64 ~ ℕ ~ <PosInt 0 LittleEndian> ~ <Seq <Digit 0>~ℤ_2^64~machine.UInt64>").unwrap()
|
||||
})
|
||||
);
|
||||
(dict, base)
|
||||
|
@ -218,7 +193,42 @@ fn test_morphgraph_map_seq() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_morphism_path3() {
|
||||
fn test_morphism_path1() {
|
||||
let (mut dict, mut base) = morphism_test_setup();
|
||||
|
||||
let morph_graph = MorphismGraph::new(base);
|
||||
|
||||
assert_eq!(
|
||||
morph_graph.search(MorphismType {
|
||||
src_type: dict.parse("ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10> ~ Char>").unwrap(),
|
||||
dst_type: dict.parse("ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>").unwrap(),
|
||||
}, &mut dict),
|
||||
Ok(
|
||||
MorphismInstance::Sub {
|
||||
ψ: dict.parse("ℕ ~ <PosInt 10 LittleEndian>").expect(""),
|
||||
m: Box::new(
|
||||
MorphismInstance::MapSeq {
|
||||
seq_repr: None,
|
||||
item_morph: Box::new(
|
||||
MorphismInstance::Specialize {
|
||||
σ: vec![
|
||||
(dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(10)),
|
||||
].into_iter().collect(),
|
||||
m: Box::new(MorphismInstance::Primitive {
|
||||
m: DummyMorphism(MorphismType {
|
||||
src_type: dict.parse("<Digit Radix> ~ Char").unwrap(),
|
||||
dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap()
|
||||
}),
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
}));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_morphism_path2() {
|
||||
let (mut dict, mut base) = morphism_test_setup();
|
||||
|
||||
let morph_graph = MorphismGraph::new(base);
|
||||
|
@ -229,11 +239,6 @@ fn test_morphism_path3() {
|
|||
dst_type: dict.parse("ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>").unwrap(),
|
||||
}, &mut dict),
|
||||
Ok(
|
||||
MorphismInstance::Specialize {
|
||||
σ: vec![
|
||||
(dict.get_typeid(&"DstRadix".into()).unwrap(), TypeTerm::Num(16)),
|
||||
].into_iter().collect(),
|
||||
m: Box::new(
|
||||
MorphismInstance::Chain {
|
||||
path: vec![
|
||||
MorphismInstance::Sub {
|
||||
|
@ -257,12 +262,12 @@ fn test_morphism_path3() {
|
|||
}
|
||||
)
|
||||
},
|
||||
|
||||
MorphismInstance::Specialize {
|
||||
σ: vec![
|
||||
(dict.get_typeid(&"SrcRadix".into()).unwrap(), TypeTerm::Num(10)),
|
||||
(dict.get_typeid(&"DstRadix".into()).unwrap(), TypeTerm::Num(16)),
|
||||
].into_iter().collect(),
|
||||
m: Box::new(
|
||||
m: Box::new(
|
||||
MorphismInstance::Primitive{
|
||||
m: DummyMorphism(MorphismType {
|
||||
src_type: dict.parse_desugared("ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict),
|
||||
|
@ -273,92 +278,96 @@ fn test_morphism_path3() {
|
|||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
}));
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_morphism_path4() {
|
||||
fn test_morphism_path3() {
|
||||
let (mut dict, mut base) = morphism_test_setup();
|
||||
|
||||
let mut morph_graph = MorphismGraph::new(base);
|
||||
|
||||
let result = morph_graph.search(MorphismType {
|
||||
src_type: dict.parse("ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10> ~ Char>").unwrap(),
|
||||
dst_type: dict.parse("ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16> ~ Char>").unwrap()
|
||||
}, &mut dict);
|
||||
|
||||
eprintln!("{:#?}", result);
|
||||
|
||||
return;
|
||||
|
||||
assert_eq!(
|
||||
morph_graph.search(MorphismType {
|
||||
src_type: dict.parse("ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10> ~ Char>").unwrap(),
|
||||
dst_type: dict.parse("ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16> ~ Char>").unwrap()
|
||||
}, &mut dict),
|
||||
result,
|
||||
|
||||
Ok(
|
||||
MorphismInstance::Specialize {
|
||||
σ: vec![
|
||||
(dict.get_typeid(&"DstRadix".into()).unwrap(), TypeTerm::Num(16)),
|
||||
].into_iter().collect(),
|
||||
m: Box::new(
|
||||
MorphismInstance::Chain {
|
||||
path: vec![
|
||||
MorphismInstance::Sub {
|
||||
ψ: dict.parse("ℕ ~ <PosInt 10 LittleEndian>").expect(""),
|
||||
m: Box::new(
|
||||
MorphismInstance::MapSeq {
|
||||
seq_repr: None,
|
||||
item_morph: Box::new(
|
||||
MorphismInstance::Specialize {
|
||||
σ: vec![
|
||||
(dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(10)),
|
||||
].into_iter().collect(),
|
||||
m: Box::new(MorphismInstance::Primitive {
|
||||
m: DummyMorphism(MorphismType {
|
||||
src_type: dict.parse("<Digit Radix> ~ Char").unwrap(),
|
||||
dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap()
|
||||
}),
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
m: Box::new(
|
||||
MorphismInstance::Chain {
|
||||
path: vec![
|
||||
|
||||
MorphismInstance::Sub {
|
||||
ψ: dict.parse("ℕ ~ <PosInt 10 LittleEndian>").expect(""),
|
||||
m: Box::new(
|
||||
MorphismInstance::MapSeq {
|
||||
seq_repr: None,
|
||||
item_morph: Box::new(
|
||||
MorphismInstance::Specialize {
|
||||
σ: vec![
|
||||
(dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(10)),
|
||||
].into_iter().collect(),
|
||||
m: Box::new(MorphismInstance::Primitive {
|
||||
m: DummyMorphism(MorphismType {
|
||||
src_type: dict.parse("<Digit Radix> ~ Char").unwrap(),
|
||||
dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap()
|
||||
}),
|
||||
})
|
||||
}
|
||||
)
|
||||
},
|
||||
}
|
||||
)
|
||||
},
|
||||
MorphismInstance::Specialize {
|
||||
σ: vec![
|
||||
(dict.get_typeid(&"SrcRadix".into()).unwrap(), TypeTerm::Num(10)),
|
||||
// (dict.get_typeid(&"DstRadix".into()).unwrap(), TypeTerm::Num(16)),
|
||||
].into_iter().collect(),
|
||||
m: Box::new(
|
||||
MorphismInstance::Primitive{
|
||||
m: DummyMorphism(MorphismType {
|
||||
src_type: dict.parse_desugared("ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict),
|
||||
dst_type: dict.parse_desugared("ℕ ~ <PosInt DstRadix LittleEndian> ~ <Seq <Digit DstRadix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict)
|
||||
}),
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
MorphismInstance::Specialize {
|
||||
σ: vec![
|
||||
(dict.get_typeid(&"SrcRadix".into()).unwrap(), TypeTerm::Num(10)),
|
||||
(dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(10)),
|
||||
].into_iter().collect(),
|
||||
m: Box::new(
|
||||
MorphismInstance::Primitive{
|
||||
m: DummyMorphism(MorphismType {
|
||||
src_type: dict.parse_desugared("ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict),
|
||||
dst_type: dict.parse_desugared("ℕ ~ <PosInt DstRadix LittleEndian> ~ <Seq <Digit DstRadix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict)
|
||||
}),
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
MorphismInstance::Sub {
|
||||
ψ: dict.parse("ℕ ~ <PosInt DstRadix LittleEndian>").expect(""),
|
||||
m: Box::new(
|
||||
MorphismInstance::MapSeq {
|
||||
seq_repr: None,
|
||||
item_morph: Box::new(
|
||||
MorphismInstance::Sub {
|
||||
ψ: dict.parse("ℕ ~ <PosInt DstRadix LittleEndian>").expect(""),
|
||||
m: Box::new(
|
||||
MorphismInstance::MapSeq {
|
||||
seq_repr: None,
|
||||
item_morph: Box::new(
|
||||
MorphismInstance::Specialize {
|
||||
σ: vec![
|
||||
(dict.get_typeid(&"Radix".into()).unwrap(), dict.parse("DstRadix").expect("")),
|
||||
].into_iter().collect(),
|
||||
m: Box::new(MorphismInstance::Primitive {
|
||||
m: DummyMorphism(MorphismType {
|
||||
src_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap(),
|
||||
dst_type: dict.parse("<Digit Radix> ~ Char").unwrap()
|
||||
}),
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
}));
|
||||
m: DummyMorphism(MorphismType {
|
||||
src_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap(),
|
||||
dst_type: dict.parse("<Digit Radix> ~ Char").unwrap()
|
||||
}),
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue