diff --git a/src/morphism_base_sugared.rs b/src/morphism_base_sugared.rs index 1fb1dcf..93d3b10 100644 --- a/src/morphism_base_sugared.rs +++ b/src/morphism_base_sugared.rs @@ -48,7 +48,7 @@ impl<M: SugaredMorphism + Clone> SugaredMorphismBase<M> { match (src_floor, dst_floor) { (SugaredTypeTerm::Struct{ struct_repr: struct_repr_lhs, members: members_lhs}, - SugaredTypeTerm::Struct { struct_repr: _struct_repr_rhs, members: members_rhs }) + SugaredTypeTerm::Struct { struct_repr: struct_repr_rhs, members: members_rhs }) => { // todo: optimization: check if struct repr match @@ -84,7 +84,8 @@ impl<M: SugaredMorphism + Clone> SugaredMorphismBase<M> { if ! failed && necessary { Some(MorphismInstance2::MapStruct { ψ: src_ψ, - struct_repr: struct_repr_lhs.clone(), + src_struct_repr: struct_repr_lhs.clone(), + dst_struct_repr: struct_repr_rhs.clone(), member_morph }) } else { diff --git a/src/morphism_sugared.rs b/src/morphism_sugared.rs index f9c36eb..5e10f65 100644 --- a/src/morphism_sugared.rs +++ b/src/morphism_sugared.rs @@ -15,7 +15,7 @@ pub struct SugaredMorphismType { impl SugaredMorphismType { pub fn strip_halo(&self) -> SugaredMorphismType { - match (&self.src_type, &self.dst_type) { + match (&self.src_type.clone().strip(), &self.dst_type.clone().strip()) { (SugaredTypeTerm::Ladder(rungs_lhs), SugaredTypeTerm::Ladder(rungs_rhs)) => { let mut lhs_iter = rungs_lhs.iter(); @@ -63,7 +63,9 @@ impl SugaredMorphismType { } } - (SugaredTypeTerm::Seq { seq_repr:seq_repr_lhs, items:items_lhs }, SugaredTypeTerm::Seq { seq_repr: seq_repr_rhs, items:items_rhs }) => { + (SugaredTypeTerm::Seq { seq_repr:seq_repr_lhs, items:items_lhs }, + SugaredTypeTerm::Seq { seq_repr: seq_repr_rhs, items:items_rhs }) + => { let (rl, rr) = items_lhs.iter().zip(items_rhs.iter()).map( |(al,ar)| SugaredMorphismType{ src_type: al.clone(), dst_type: ar.clone() }.strip_halo() ) @@ -78,12 +80,15 @@ impl SugaredMorphismType { } } - (SugaredTypeTerm::Struct { struct_repr:seq_repr_lhs, members:items_lhs }, SugaredTypeTerm::Struct { struct_repr: seq_repr_rhs, members:items_rhs }) => { + (SugaredTypeTerm::Struct { struct_repr:struct_repr_lhs, members:members_lhs }, + SugaredTypeTerm::Struct { struct_repr: struct_repr_rhs, members:members_rhs }) + => { let mut rl = Vec::new(); let mut rr = Vec::new(); - for ar in items_rhs.iter() { - for al in items_lhs.iter() { + for ar in members_rhs.iter() { + let mut found = false; + for al in members_lhs.iter() { if al.symbol == ar.symbol { let x = SugaredMorphismType{ src_type: al.ty.clone(), dst_type: ar.ty.clone() }.strip_halo(); rl.push( SugaredStructMember{ @@ -94,24 +99,34 @@ impl SugaredMorphismType { symbol: ar.symbol.clone(), ty: x.dst_type }); + found = true; break; } } + + if !found { + return SugaredMorphismType { + src_type: SugaredTypeTerm::Struct { struct_repr: struct_repr_lhs.clone(), members:members_lhs.clone() }, + dst_type: SugaredTypeTerm::Struct { struct_repr: struct_repr_rhs.clone(), members:members_rhs.clone() } + }; + } } SugaredMorphismType { - src_type: SugaredTypeTerm::Struct{ struct_repr: seq_repr_lhs.clone(), members: rl }, - dst_type: SugaredTypeTerm::Struct{ struct_repr: seq_repr_rhs.clone(), members: rr } + src_type: SugaredTypeTerm::Struct{ struct_repr: struct_repr_lhs.clone(), members: rl }, + dst_type: SugaredTypeTerm::Struct{ struct_repr: struct_repr_rhs.clone(), members: rr } } } - (SugaredTypeTerm::Enum { enum_repr:seq_repr_lhs, variants:items_lhs }, SugaredTypeTerm::Enum { enum_repr: seq_repr_rhs, variants:items_rhs }) => { - + (SugaredTypeTerm::Enum { enum_repr:enum_repr_lhs, variants:variants_lhs }, + SugaredTypeTerm::Enum { enum_repr: enum_repr_rhs, variants:variants_rhs }) + => { let mut rl = Vec::new(); let mut rr = Vec::new(); - for ar in items_rhs.iter() { - for al in items_lhs.iter() { + for ar in variants_rhs.iter() { + let mut found = false; + for al in variants_lhs.iter() { if al.symbol == ar.symbol { let x = SugaredMorphismType{ src_type: al.ty.clone(), dst_type: ar.ty.clone() }.strip_halo(); rl.push( SugaredEnumVariant{ @@ -122,13 +137,22 @@ impl SugaredMorphismType { symbol: ar.symbol.clone(), ty: x.dst_type }); + found = true; + break; } } + + if !found { + return SugaredMorphismType { + src_type: SugaredTypeTerm::Enum { enum_repr: enum_repr_lhs.clone(), variants:variants_lhs.clone() }, + dst_type: SugaredTypeTerm::Enum { enum_repr: enum_repr_rhs.clone(), variants:variants_rhs.clone() } + }; + } } SugaredMorphismType { - src_type: SugaredTypeTerm::Enum{ enum_repr: seq_repr_lhs.clone(), variants: rl }, - dst_type: SugaredTypeTerm::Enum { enum_repr: seq_repr_rhs.clone(), variants: rr } + src_type: SugaredTypeTerm::Enum{ enum_repr: enum_repr_lhs.clone(), variants: rl }, + dst_type: SugaredTypeTerm::Enum { enum_repr: enum_repr_rhs.clone(), variants: rr } } } @@ -151,7 +175,7 @@ pub trait SugaredMorphism : Sized { } } -#[derive(Clone)] +#[derive(Clone, PartialEq, Debug)] pub enum MorphismInstance2<M: SugaredMorphism + Clone> { Primitive{ ψ: SugaredTypeTerm, @@ -168,7 +192,8 @@ pub enum MorphismInstance2<M: SugaredMorphism + Clone> { }, MapStruct{ ψ: SugaredTypeTerm, - struct_repr: Option<Box<SugaredTypeTerm>>, + src_struct_repr: Option<Box<SugaredTypeTerm>>, + dst_struct_repr: Option<Box<SugaredTypeTerm>>, member_morph: Vec< (String, MorphismInstance2<M>) > }, MapEnum{ @@ -204,14 +229,15 @@ impl<M: SugaredMorphism + Clone> MorphismInstance2<M> { } MorphismInstance2::Chain { path } => { if path.len() > 0 { + let s = self.get_subst(); SugaredMorphismType { - src_type: path.first().unwrap().get_type().src_type, - dst_type: path.last().unwrap().get_type().dst_type + src_type: path.first().unwrap().get_type().src_type.clone().apply_subst(&s).clone(), + dst_type: path.last().unwrap().get_type().dst_type.clone().apply_subst(&s).clone() } } else { SugaredMorphismType { - src_type: SugaredTypeTerm::TypeID(TypeID::Var(45454)), - dst_type: SugaredTypeTerm::TypeID(TypeID::Var(45454)) + src_type: SugaredTypeTerm::TypeID(TypeID::Fun(45454)), + dst_type: SugaredTypeTerm::TypeID(TypeID::Fun(45454)) } } } @@ -229,11 +255,11 @@ impl<M: SugaredMorphism + Clone> MorphismInstance2<M> { ]).strip() } } - MorphismInstance2::MapStruct { ψ, struct_repr, member_morph } => { + MorphismInstance2::MapStruct { ψ, src_struct_repr, dst_struct_repr, member_morph } => { SugaredMorphismType { src_type: SugaredTypeTerm::Ladder(vec![ ψ.clone(), SugaredTypeTerm::Struct{ - struct_repr: struct_repr.clone(), + struct_repr: src_struct_repr.clone(), members: member_morph.iter().map(|(symbol, morph)| { SugaredStructMember{ symbol:symbol.clone(), ty: morph.get_type().src_type } @@ -242,7 +268,7 @@ impl<M: SugaredMorphism + Clone> MorphismInstance2<M> { ]).strip(), dst_type: SugaredTypeTerm::Ladder(vec![ ψ.clone(), SugaredTypeTerm::Struct{ - struct_repr: struct_repr.clone(), + struct_repr: dst_struct_repr.clone(), members: member_morph.iter().map(|(symbol, morph)| { SugaredStructMember { symbol: symbol.clone(), ty: morph.get_type().dst_type} }).collect() @@ -289,7 +315,7 @@ impl<M: SugaredMorphism + Clone> MorphismInstance2<M> { MorphismInstance2::MapSeq { ψ, seq_repr, item_morph } => { item_morph.get_subst() }, - MorphismInstance2::MapStruct { ψ, struct_repr, member_morph } => { + MorphismInstance2::MapStruct { ψ, src_struct_repr, dst_struct_repr, member_morph } => { let mut σ = HashMap::new(); for (symbol, m) in member_morph.iter() { σ = σ.append(&mut m.get_subst()); @@ -304,10 +330,21 @@ impl<M: SugaredMorphism + Clone> MorphismInstance2<M> { } pub fn apply_subst(&mut self, γ: &std::collections::HashMap< TypeID, SugaredTypeTerm >) { + let ty = self.get_type(); match self { MorphismInstance2::Primitive { ψ, σ, morph } => { - ψ.apply_subst(σ); - *σ = σ.clone().append(γ); + ψ.apply_subst(γ); + for (n,t) in σ.iter_mut() { + t.apply_subst(γ); + } + for (n,t) in γ.iter() { + if let TypeID::Var(varid) = n { + if morph.get_type().src_type.apply_subst(σ).contains_var(*varid) + || morph.get_type().dst_type.apply_subst(σ).contains_var(*varid) { + σ.insert(n.clone(), t.clone()); + } + } + } }, MorphismInstance2::Chain { path } => { for n in path.iter_mut() { @@ -318,7 +355,7 @@ impl<M: SugaredMorphism + Clone> MorphismInstance2<M> { ψ.apply_subst(γ); item_morph.apply_subst(γ); } - MorphismInstance2::MapStruct { ψ, struct_repr, member_morph } => { + MorphismInstance2::MapStruct { ψ, src_struct_repr, dst_struct_repr, member_morph } => { for (_,ty) in member_morph { ty.apply_subst(γ); } diff --git a/src/test/morphism.rs b/src/test/morphism.rs index dbc03dc..56d3059 100644 --- a/src/test/morphism.rs +++ b/src/test/morphism.rs @@ -1,99 +1,82 @@ use { - crate::{dict::*, parser::*, unparser::*, morphism::*, TypeTerm, morphism_base::*, morphism_path::*} + crate::{dict::*, morphism::*, morphism_base::*, morphism_base_sugared::SugaredMorphismBase, morphism_path::*, morphism_path_sugared::SugaredShortestPathProblem, morphism_sugared::{MorphismInstance2, SugaredMorphism, SugaredMorphismType}, parser::*, unparser::*, SugaredTypeTerm, TypeTerm} }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\ -fn print_subst(m: &std::collections::HashMap<TypeID, TypeTerm>, dict: &mut impl TypeDict) { +fn print_subst(m: &std::collections::HashMap<TypeID, SugaredTypeTerm>, dict: &mut impl TypeDict) { eprintln!("{{"); for (k,v) in m.iter() { eprintln!(" {} --> {}", dict.get_typename(k).unwrap(), - dict.unparse(v) + v.pretty(dict, 0) ); } eprintln!("}}"); } -fn print_path(dict: &mut impl TypeDict, path: &Vec<MorphismInstance<DummyMorphism>>) { +fn print_path(dict: &mut impl TypeDict, path: &Vec<MorphismInstance2<DummyMorphism>>) { for n in path.iter() { eprintln!(" -ψ = {} morph {} --> {} with ", - n.halo.clone().sugar(dict).pretty(dict, 0), - n.m.get_type().src_type.sugar(dict).pretty(dict, 0), - n.m.get_type().dst_type.sugar(dict).pretty(dict, 0), + n.get_type().src_type.pretty(dict, 0), + n.get_type().dst_type.pretty(dict, 0), ); - print_subst(&n.σ, dict) + print_subst(&n.get_subst(), dict) } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\ -#[derive(Clone, Debug, PartialEq)] -struct DummyMorphism(MorphismType); - -impl Morphism for DummyMorphism { - fn get_type(&self) -> MorphismType { - self.0.clone().normalize() - } - - fn map_morphism(&self, seq_type: TypeTerm) -> Option<DummyMorphism> { - Some(DummyMorphism(MorphismType { - src_type: TypeTerm::App(vec![ - seq_type.clone(), - self.0.src_type.clone() - ]), - - dst_type: TypeTerm::App(vec![ - seq_type.clone(), - self.0.dst_type.clone() - ]) - })) +#[derive(Clone, Debug, PartialEq, Eq)] +struct DummyMorphism(SugaredMorphismType); +impl SugaredMorphism for DummyMorphism { + fn get_type(&self) -> SugaredMorphismType { + self.0.clone() } } -fn morphism_test_setup() -> ( BimapTypeDict, MorphismBase<DummyMorphism> ) { +fn morphism_test_setup() -> ( BimapTypeDict, SugaredMorphismBase<DummyMorphism> ) { let mut dict = BimapTypeDict::new(); - let mut base = MorphismBase::<DummyMorphism>::new( vec![ dict.parse("Seq").expect("") ] ); + let mut base = SugaredMorphismBase::<DummyMorphism>::new(); dict.add_varname("Radix".into()); dict.add_varname("SrcRadix".into()); dict.add_varname("DstRadix".into()); base.add_morphism( - DummyMorphism(MorphismType{ - src_type: dict.parse("<Digit Radix> ~ Char").unwrap(), - dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap() + DummyMorphism(SugaredMorphismType{ + src_type: dict.parse("<Digit Radix> ~ Char").unwrap().sugar(&mut dict), + dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict) }) ); base.add_morphism( - DummyMorphism(MorphismType{ - src_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap(), - dst_type: dict.parse("<Digit Radix> ~ Char").unwrap() + DummyMorphism(SugaredMorphismType{ + src_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict), + dst_type: dict.parse("<Digit Radix> ~ Char").unwrap().sugar(&mut dict) }) ); base.add_morphism( - DummyMorphism(MorphismType{ - 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() + DummyMorphism(SugaredMorphismType{ + src_type: dict.parse("ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict) }) ); base.add_morphism( - DummyMorphism(MorphismType{ - 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() + DummyMorphism(SugaredMorphismType{ + src_type: dict.parse("ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit Radix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict) }) ); base.add_morphism( - DummyMorphism(MorphismType{ - 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() + DummyMorphism(SugaredMorphismType{ + src_type: dict.parse("ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt DstRadix LittleEndian> ~ <Seq <Digit DstRadix>~ℤ_2^64~machine.UInt64>").unwrap().sugar(&mut dict) }) ); @@ -104,23 +87,23 @@ fn morphism_test_setup() -> ( BimapTypeDict, MorphismBase<DummyMorphism> ) { fn test_morphism_path1() { let (mut dict, mut base) = morphism_test_setup(); - let path = ShortestPathProblem::new(&base, MorphismType { - src_type: dict.parse("<Digit 10> ~ Char").unwrap(), - dst_type: dict.parse("<Digit 10> ~ ℤ_2^64 ~ machine.UInt64").unwrap(), + let path = SugaredShortestPathProblem::new(&base, SugaredMorphismType { + src_type: dict.parse("<Digit 10> ~ Char").unwrap().sugar(&mut dict), + dst_type: dict.parse("<Digit 10> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict), }).solve(); assert_eq!( path, Some( vec![ - MorphismInstance { + MorphismInstance2::Primitive { σ: vec![ - (dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(10)), + (dict.get_typeid(&"Radix".into()).unwrap(), SugaredTypeTerm::Num(10)), ].into_iter().collect(), - halo: TypeTerm::unit(), - m: DummyMorphism(MorphismType { - src_type: dict.parse("<Digit Radix> ~ Char").unwrap(), - dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap() + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType { + src_type: dict.parse("<Digit Radix> ~ Char").unwrap().sugar(&mut dict), + dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict) }), } ] @@ -132,24 +115,28 @@ fn test_morphism_path1() { fn test_morphism_path2() { let (mut dict, mut base) = morphism_test_setup(); - let path = ShortestPathProblem::new(&base, MorphismType { - src_type: dict.parse("ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10> ~ Char>").unwrap(), - dst_type: dict.parse("ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>").unwrap(), + let path = SugaredShortestPathProblem::new(&base, SugaredMorphismType { + src_type: dict.parse("ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10> ~ Char>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict), }).solve(); assert_eq!( path, Some( vec![ - MorphismInstance { - σ: vec![ - (dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(10)), - ].into_iter().collect(), - halo: dict.parse("ℕ ~ <PosInt 10 BigEndian>").expect(""), - m: DummyMorphism(MorphismType { - src_type: dict.parse("<Seq <Digit Radix> ~ Char>").unwrap(), - dst_type: dict.parse("<Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap() - }), + MorphismInstance2::MapSeq { + ψ: dict.parse("ℕ ~ <PosInt 10 BigEndian>").expect("").sugar(&mut dict), + seq_repr: None, + item_morph: Box::new(MorphismInstance2::Primitive { + σ: vec![ + (dict.get_typeid(&"Radix".into()).unwrap(), SugaredTypeTerm::Num(10)), + ].into_iter().collect(), + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType { + src_type: dict.parse("<Digit Radix> ~ Char").unwrap().sugar(&mut dict), + dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict) + }), + }) } ] )); @@ -160,9 +147,9 @@ fn test_morphism_path2() { fn test_morphism_path3() { let (mut dict, mut base) = morphism_test_setup(); - let path = ShortestPathProblem::new(&base, MorphismType { - src_type: dict.parse("ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10> ~ Char>").unwrap(), - dst_type: dict.parse("ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>").unwrap(), + let path = SugaredShortestPathProblem::new(&base, SugaredMorphismType { + src_type: dict.parse("ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10> ~ Char>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict), }).solve(); if let Some(path) = path.as_ref() { @@ -173,26 +160,30 @@ fn test_morphism_path3() { path, Some( vec![ - MorphismInstance { - σ: vec![ - (dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(10)), - ].into_iter().collect(), - halo: dict.parse("ℕ ~ <PosInt 10 LittleEndian>").expect(""), - m: DummyMorphism(MorphismType { - src_type: dict.parse("<Seq <Digit Radix> ~ Char>").unwrap(), - dst_type: dict.parse("<Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap() - }), + MorphismInstance2::MapSeq { + ψ: dict.parse("ℕ ~ <PosInt 10 LittleEndian>").expect("").sugar(&mut dict), + seq_repr: None, + item_morph: Box::new(MorphismInstance2::Primitive { + σ: vec![ + (dict.get_typeid(&"Radix".into()).unwrap(), SugaredTypeTerm::Num(10)), + ].into_iter().collect(), + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType { + src_type: dict.parse("<Digit Radix> ~ Char").unwrap().sugar(&mut dict), + dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict) + }), + }) }, - MorphismInstance { + MorphismInstance2::Primitive { σ: vec![ - (dict.get_typeid(&"SrcRadix".into()).unwrap(), TypeTerm::Num(10)), - (dict.get_typeid(&"DstRadix".into()).unwrap(), TypeTerm::Num(16)), + (dict.get_typeid(&"SrcRadix".into()).unwrap(), SugaredTypeTerm::Num(10)), + (dict.get_typeid(&"DstRadix".into()).unwrap(), SugaredTypeTerm::Num(16)), ].into_iter().collect(), - halo: TypeTerm::unit(), - m: DummyMorphism(MorphismType { - 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() + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType { + src_type: dict.parse("ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt DstRadix LittleEndian> ~ <Seq <Digit DstRadix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict) }), } ] @@ -205,9 +196,9 @@ fn test_morphism_path3() { fn test_morphism_path4() { let (mut dict, mut base) = morphism_test_setup(); - let path = ShortestPathProblem::new(&base, 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() + let path = SugaredShortestPathProblem::new(&base, SugaredMorphismType { + src_type: dict.parse("ℕ ~ <PosInt 10 LittleEndian> ~ <Seq <Digit 10> ~ Char>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt 16 LittleEndian> ~ <Seq <Digit 16> ~ Char>").unwrap().sugar(&mut dict) }).solve(); if let Some(path) = path.as_ref() { @@ -218,40 +209,47 @@ fn test_morphism_path4() { path, Some( vec![ - MorphismInstance { + MorphismInstance2::MapSeq { + ψ: dict.parse("ℕ ~ <PosInt 10 LittleEndian>").expect("").sugar(&mut dict), + seq_repr: None, + item_morph: Box::new(MorphismInstance2::Primitive { + σ: vec![ + (dict.get_typeid(&"Radix".into()).unwrap(), SugaredTypeTerm::Num(10)), + ].into_iter().collect(), + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType { + src_type: dict.parse("<Digit Radix> ~ Char").unwrap().sugar(&mut dict), + dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict) + }), + }) + }, + + MorphismInstance2::Primitive { σ: vec![ - (dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(10)), + (dict.get_typeid(&"SrcRadix".into()).unwrap(), SugaredTypeTerm::Num(10)), + (dict.get_typeid(&"DstRadix".into()).unwrap(), SugaredTypeTerm::Num(16)), ].into_iter().collect(), - halo: dict.parse("ℕ ~ <PosInt 10 LittleEndian>").expect(""), - m: DummyMorphism(MorphismType { - src_type: dict.parse("<Seq <Digit Radix> ~ Char>").unwrap(), - dst_type: dict.parse("<Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap() + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType { + src_type: dict.parse("ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt DstRadix LittleEndian> ~ <Seq <Digit DstRadix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict) }), }, - MorphismInstance { - σ: vec![ - (dict.get_typeid(&"SrcRadix".into()).unwrap(), TypeTerm::Num(10)), - (dict.get_typeid(&"DstRadix".into()).unwrap(), TypeTerm::Num(16)), - ].into_iter().collect(), - halo: TypeTerm::unit(), - m: DummyMorphism(MorphismType { - 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() - }), + MorphismInstance2::MapSeq { + ψ: dict.parse("ℕ ~ <PosInt 16 LittleEndian>").expect("").sugar(&mut dict), + seq_repr: None, + item_morph: Box::new(MorphismInstance2::Primitive { + σ: vec![ + (dict.get_typeid(&"Radix".into()).unwrap(), SugaredTypeTerm::Num(16)), + ].into_iter().collect(), + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType { + src_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict), + dst_type: dict.parse("<Digit Radix> ~ Char").unwrap().sugar(&mut dict) + }), + }) }, - - MorphismInstance { - σ: vec![ - (dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(16)), - ].into_iter().collect(), - halo: dict.parse("ℕ ~ <PosInt 16 LittleEndian>").expect(""), - m: DummyMorphism(MorphismType { - src_type: dict.parse("<Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap(), - dst_type: dict.parse("<Seq <Digit Radix> ~ Char>").unwrap() - }), - }, - ] )); } @@ -263,9 +261,9 @@ fn test_morphism_path4() { fn test_morphism_path_posint() { let (mut dict, mut base) = morphism_test_setup(); - let path = ShortestPathProblem::new(&base, MorphismType { - src_type: dict.parse("ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10> ~ Char>").unwrap(), - dst_type: dict.parse("ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16> ~ Char>").unwrap(), + let path = SugaredShortestPathProblem::new(&base, SugaredMorphismType { + src_type: dict.parse("ℕ ~ <PosInt 10 BigEndian> ~ <Seq <Digit 10> ~ Char>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt 16 BigEndian> ~ <Seq <Digit 16> ~ Char>").unwrap().sugar(&mut dict), }).solve(); if let Some(path) = path.as_ref() { @@ -276,62 +274,72 @@ fn test_morphism_path_posint() { path, Some( vec![ - MorphismInstance { - σ: vec![ - (dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(10)), - ].into_iter().collect(), - halo: dict.parse("ℕ ~ <PosInt 10 BigEndian>").unwrap(), - m: DummyMorphism(MorphismType { - src_type: dict.parse("<Seq <Digit Radix> ~ Char>").unwrap(), - dst_type: dict.parse("<Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap() - }), - }, - MorphismInstance { - σ: vec![ - (dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(10)), - ].into_iter().collect(), - halo: TypeTerm::unit(), - m: DummyMorphism(MorphismType{ - 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() - }), - }, - MorphismInstance { - σ: vec![ - (dict.get_typeid(&"SrcRadix".into()).unwrap(), TypeTerm::Num(10)), - (dict.get_typeid(&"DstRadix".into()).unwrap(), TypeTerm::Num(16)), - ].into_iter().collect(), - halo: TypeTerm::unit(), - m: DummyMorphism(MorphismType{ - 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() - }), - }, - MorphismInstance { - σ: vec![ - (dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(16)), - ].into_iter().collect(), - halo: TypeTerm::unit(), - m: DummyMorphism(MorphismType{ - 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(), - }), - }, - MorphismInstance { - σ: vec![ - (dict.get_typeid(&"Radix".into()).unwrap(), TypeTerm::Num(16)) - ].into_iter().collect(), - halo: dict.parse("ℕ ~ <PosInt 16 BigEndian>").unwrap(), - m: DummyMorphism(MorphismType{ - src_type: dict.parse("<Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap(), - dst_type: dict.parse("<Seq <Digit Radix> ~ Char>").unwrap() + MorphismInstance2::MapSeq { + ψ: dict.parse("ℕ ~ <PosInt 10 BigEndian>").expect("").sugar(&mut dict), + seq_repr: None, + item_morph: Box::new(MorphismInstance2::Primitive { + σ: vec![ + (dict.get_typeid(&"Radix".into()).unwrap(), SugaredTypeTerm::Num(10)), + ].into_iter().collect(), + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType { + src_type: dict.parse("<Digit Radix> ~ Char").unwrap().sugar(&mut dict), + dst_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict) + }), }) - } + }, + + MorphismInstance2::Primitive { + σ: vec![ + (dict.get_typeid(&"Radix".into()).unwrap(), SugaredTypeTerm::Num(10)), + ].into_iter().collect(), + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType{ + src_type: dict.parse("ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict) + }), + }, + MorphismInstance2::Primitive { + σ: vec![ + (dict.get_typeid(&"SrcRadix".into()).unwrap(), SugaredTypeTerm::Num(10)), + (dict.get_typeid(&"DstRadix".into()).unwrap(), SugaredTypeTerm::Num(16)), + ].into_iter().collect(), + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType{ + src_type: dict.parse("ℕ ~ <PosInt SrcRadix LittleEndian> ~ <Seq <Digit SrcRadix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt DstRadix LittleEndian> ~ <Seq <Digit DstRadix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict) + }), + }, + MorphismInstance2::Primitive { + σ: vec![ + (dict.get_typeid(&"Radix".into()).unwrap(), SugaredTypeTerm::Num(16)), + ].into_iter().collect(), + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType{ + src_type: dict.parse("ℕ ~ <PosInt Radix LittleEndian> ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict), + dst_type: dict.parse("ℕ ~ <PosInt Radix BigEndian> ~ <Seq <Digit Radix> ~ ℤ_2^64 ~ machine.UInt64>").unwrap().sugar(&mut dict), + }), + }, + + MorphismInstance2::MapSeq { + ψ: dict.parse("ℕ ~ <PosInt 16 BigEndian>").expect("").sugar(&mut dict), + seq_repr: None, + item_morph: Box::new(MorphismInstance2::Primitive { + σ: vec![ + (dict.get_typeid(&"Radix".into()).unwrap(), SugaredTypeTerm::Num(16)), + ].into_iter().collect(), + ψ: SugaredTypeTerm::unit(), + morph: DummyMorphism(SugaredMorphismType { + src_type: dict.parse("<Digit Radix> ~ ℤ_2^64 ~ machine.UInt64").unwrap().sugar(&mut dict), + dst_type: dict.parse("<Digit Radix> ~ Char").unwrap().sugar(&mut dict) + }), + }) + }, ] ) ); } - +/* #[test] fn test_steiner_tree() { let (mut dict, mut base) = morphism_test_setup(); @@ -459,3 +467,4 @@ fn test_morphism_path_listedit() ]) ); } +*/ diff --git a/src/test/unification.rs b/src/test/unification.rs index ae99a18..aa20398 100644 --- a/src/test/unification.rs +++ b/src/test/unification.rs @@ -397,7 +397,7 @@ fn test_list_subtype_sugared() { ]; assert_eq!( - SugaredUnificationProblem::new_sub(&mut dict, subtype_constraints).solve(), + SugaredUnificationProblem::new_sub(subtype_constraints).solve(), Ok(( vec![ SugaredTypeTerm::Ladder(vec![]) ], vec![ @@ -437,7 +437,7 @@ pub fn test_subtype_delim_sugared() { ]; assert_eq!( - SugaredUnificationProblem::new_sub(&mut dict, subtype_constraints).solve(), + SugaredUnificationProblem::new_sub(subtype_constraints).solve(), Ok(( // halo types for each rhs in the sub-equations vec![ diff --git a/src/unification_sugared.rs b/src/unification_sugared.rs index 499e2f1..c3e631e 100644 --- a/src/unification_sugared.rs +++ b/src/unification_sugared.rs @@ -138,7 +138,17 @@ impl SugaredUnificationProblem { (SugaredTypeTerm::Seq{ seq_repr: lhs_seq_repr, items: lhs_items }, SugaredTypeTerm::Seq { seq_repr: rhs_seq_repr, items: rhs_items }) => { - // todo: unify seq reprü + let mut new_addr = unification_pair.addr.clone(); + new_addr.push(0); + + if let Some(rhs_seq_repr) = rhs_seq_repr.as_ref() { + if let Some(lhs_seq_repr) = lhs_seq_repr.as_ref() { + let _seq_repr_ψ = self.eval_equation(SugaredUnificationPair { addr: new_addr.clone(), lhs: *lhs_seq_repr.clone(), rhs: *rhs_seq_repr.clone() })?; + } else { + return Err(SugaredUnificationError{ addr: new_addr, t1: unification_pair.lhs, t2: unification_pair.rhs }); + } + } + if lhs_items.len() == rhs_items.len() { for (i, (lhs_ty, rhs_ty)) in lhs_items.into_iter().zip(rhs_items.into_iter()).enumerate() @@ -155,7 +165,14 @@ impl SugaredUnificationProblem { (SugaredTypeTerm::Struct{ struct_repr: lhs_struct_repr, members: lhs_members }, SugaredTypeTerm::Struct{ struct_repr: rhs_struct_repr, members: rhs_members }) => { - // todo: unify struct repr + let new_addr = unification_pair.addr.clone(); + if let Some(rhs_struct_repr) = rhs_struct_repr.as_ref() { + if let Some(lhs_struct_repr) = lhs_struct_repr.as_ref() { + let _struct_repr_ψ = self.eval_subtype(SugaredUnificationPair { addr: new_addr.clone(), lhs: *lhs_struct_repr.clone(), rhs: *rhs_struct_repr.clone() })?; + } else { + return Err(SugaredUnificationError{ addr: new_addr.clone(), t1: unification_pair.lhs, t2: unification_pair.rhs }); + } + } if lhs_members.len() == rhs_members.len() { for (i, @@ -176,7 +193,15 @@ impl SugaredUnificationProblem { (SugaredTypeTerm::Enum{ enum_repr: lhs_enum_repr, variants: lhs_variants }, SugaredTypeTerm::Enum{ enum_repr: rhs_enum_repr, variants: rhs_variants }) => { - // todo: unify enum repr + let mut new_addr = unification_pair.addr.clone(); + if let Some(rhs_enum_repr) = rhs_enum_repr.as_ref() { + if let Some(lhs_enum_repr) = lhs_enum_repr.as_ref() { + let _enum_repr_ψ = self.eval_subtype(SugaredUnificationPair { addr: new_addr.clone(), lhs: *lhs_enum_repr.clone(), rhs: *rhs_enum_repr.clone() })?; + } else { + return Err(SugaredUnificationError{ addr: new_addr, t1: unification_pair.lhs, t2: unification_pair.rhs }); + } + } + if lhs_variants.len() == rhs_variants.len() { for (i,