use std::rc::Rc;
use ast::*;
use bitype;
use bitype::{Ctx,Term};
use subst;
#[derive(Clone,Debug,Eq,PartialEq,Hash,Serialize,PartialOrd,Ord)]
pub enum NmSetTm {
Single(NameTm),
Subset(IdxTm),
}
pub type NmSetTms = Vec<NmSetTm>;
#[derive(Clone,Debug,Eq,PartialEq,Hash,Serialize,PartialOrd,Ord)]
pub enum NmSetCons {
Union,
Apart,
}
#[derive(Clone,Debug,Eq,PartialEq,Hash,Serialize,PartialOrd,Ord)]
pub struct NmSet {
pub cons: Option<NmSetCons>,
pub terms: Vec<NmSetTm>
}
fn nmset_terms_add(cons:Option<NmSetCons>, terms:&mut Vec<NmSetTm>, tm:NmSetTm) {
match tm {
NmSetTm::Subset(i) => {
match i {
IdxTm::NmSet(mut ns) => {
assert_eq!(cons, ns.cons);
terms.append(&mut ns.terms)
}
i => {
terms.push(NmSetTm::Subset(i))
}
}
}
tm => {
terms.push(tm)
}
}
}
pub fn is_normal_nmtm(_ctx:&Ctx, n:&NameTm) -> bool {
match *n {
NameTm::Var(_) |
NameTm::ValVar(_) |
NameTm::Name(_) |
NameTm::Lam(_,_,_) => true,
NameTm::WriteScope => true,
NameTm::Bin(_,_) |
NameTm::App(_,_) => false,
NameTm::Ident(_) => false,
NameTm::NoParse(_) => false,
}
}
pub fn is_normal_idxtm(ctx:&Ctx, i:&IdxTm) -> bool {
match *i {
IdxTm::Ident(_) => false,
IdxTm::Var(_) => true,
IdxTm::Unit => true,
IdxTm::NmSet(_) => true,
IdxTm::WriteScope => true,
IdxTm::Lam(_,_,_) => true,
IdxTm::Pair(ref i, ref j) |
IdxTm::Union(ref i, ref j) => {
is_normal_idxtm(ctx, i) && is_normal_idxtm(ctx, j)
},
IdxTm::Proj1(_) => false,
IdxTm::Proj2(_) => false,
IdxTm::Empty |
IdxTm::Sing(_) |
IdxTm::Apart(_, _) |
IdxTm::App(_, _) |
IdxTm::Bin(_, _) |
IdxTm::Map(_, _) |
IdxTm::MapStar(_, _) |
IdxTm::FlatMap(_, _) |
IdxTm::FlatMapStar(_, _) |
IdxTm::NoParse(_) => false
}
}
pub fn normal_idxtm_rec(ctx:&Ctx, i:Rc<IdxTm>) -> Rc<IdxTm> {
Rc::new(normal_idxtm(ctx, (*i).clone()))
}
pub fn normal_idxtm(ctx:&Ctx, i:IdxTm) -> IdxTm {
if is_normal_idxtm(ctx, &i) {
return i
} else {
match i {
IdxTm::Empty => {
IdxTm::NmSet(NmSet{cons:None, terms:vec![]})
}
IdxTm::Sing(n) => {
let n = normal_nmtm(ctx, n);
IdxTm::NmSet(NmSet{cons:None, terms:vec![
NmSetTm::Single( n )
]})
}
IdxTm::Ident(ref ident) => {
match ctx.lookup_idxtm_def(ident) {
Some(i) => normal_idxtm(ctx, i),
_ => {
println!("undefined idxtm: {} in\n{:?}", ident, ctx);
i.clone()
}
}
}
IdxTm::Apart(i1, i2) => {
let i1 = normal_idxtm_rec(ctx, i1);
let i2 = normal_idxtm_rec(ctx, i2);
match ((*i1).clone(), (*i2).clone()) {
(IdxTm::NmSet(ns1),
IdxTm::NmSet(ns2)) => {
match (ns1.cons, ns2.cons) {
(None, None) |
(None, Some(NmSetCons::Apart)) |
(Some(NmSetCons::Apart), None) |
(Some(NmSetCons::Apart), Some(NmSetCons::Apart)) => {
let mut terms1 = ns1.terms;
let mut terms2 = ns2.terms;
terms1.append(&mut terms2);
IdxTm::NmSet(NmSet{
cons:Some(NmSetCons::Apart),
terms:terms1
})
},
_ => IdxTm::Apart(i1, i2)
}}
(i, IdxTm::NmSet(mut ns)) |
(IdxTm::NmSet(mut ns), i) => {
nmset_terms_add(ns.cons.clone(), &mut ns.terms, NmSetTm::Subset(i));
IdxTm::NmSet(ns)
}
_ => {
IdxTm::NmSet(NmSet{
cons:Some(NmSetCons::Apart),
terms:vec![NmSetTm::Subset((*i1).clone()),
NmSetTm::Subset((*i2).clone())],
})
}
}
}
IdxTm::Union(i1, i2) => {
let i1 = normal_idxtm_rec(ctx, i1);
let i2 = normal_idxtm_rec(ctx, i2);
match ((*i1).clone(), (*i2).clone()) {
(IdxTm::NmSet(ns1),
IdxTm::NmSet(ns2)) => {
let mut terms1 = ns1.terms;
let mut terms2 = ns2.terms;
terms1.append(&mut terms2);
IdxTm::NmSet(NmSet{
cons:Some(NmSetCons::Union),
terms:terms1
})
}
(i, IdxTm::NmSet(mut ns)) |
(IdxTm::NmSet(mut ns), i) => {
nmset_terms_add(ns.cons.clone(), &mut ns.terms, NmSetTm::Subset(i));
IdxTm::NmSet(ns)
}
_ => {
IdxTm::NmSet(NmSet{
cons:Some(NmSetCons::Union),
terms:vec![NmSetTm::Subset((*i1).clone()),
NmSetTm::Subset((*i2).clone())],
})
}
}
}
IdxTm::Bin(i1, i2) => {
use self::NmSetTm::*;
let i1 = normal_idxtm_rec(ctx, i1);
let i2 = normal_idxtm_rec(ctx, i2);
fn bin_tm (ctx:&Ctx, tm1:NmSetTm, tm2:NmSetTm) -> NmSetTm { match (tm1, tm2) {
(Single(n), Single(m)) => {
Single(normal_nmtm(
ctx, NameTm::Bin(Rc::new(n), Rc::new(m))
))
},
(Subset(i), Single(m)) => {
Subset( normal_idxtm(
ctx, fgi_index!{
[ #x:Nm. x, ^m ] ^i
}
))
},
(Single(n), Subset(j)) => {
Subset(normal_idxtm(
ctx, fgi_index!{
[ #x:Nm. ^n, x ] ^j
}
))
},
(Subset(IdxTm::Var(ref x_w_def)), Subset(ref j))
if None != bitype::find_defs_for_idxtm_var(&ctx, x_w_def)
=>
{ let xdef = bitype::find_defs_for_idxtm_var(&ctx, x_w_def);
match normal_idxtm(ctx, xdef.unwrap()) {
IdxTm::NmSet(ns) => {
let mut terms = vec![];
for t in ns.terms.iter() {
match t {
&NmSetTm::Single(ref n) => {
let tm = normal_idxtm(ctx, IdxTm::Bin(Rc::new(IdxTm::Sing(n.clone())), Rc::new(j.clone())));
nmset_terms_add(ns.cons.clone(), &mut terms, NmSetTm::Subset(tm))
}
&NmSetTm::Subset(ref i) => {
let tm = normal_idxtm(ctx, IdxTm::Bin(Rc::new(i.clone()), Rc::new(j.clone())));
nmset_terms_add(ns.cons.clone(), &mut terms, NmSetTm::Subset(tm));
}
}
};
Subset(IdxTm::NmSet(NmSet{
cons:ns.cons.clone(),
terms:terms,
}))
},
_ => {
Subset(normal_idxtm(
ctx, IdxTm::Bin(Rc::new(IdxTm::Var(x_w_def.clone())),Rc::new(j.clone()))
))
}
}
}
(Subset(i), Subset(j)) => {
Subset(IdxTm::Bin(
Rc::new(i),
Rc::new(j)
))
},
}};
match ((*i1).clone(), (*i2).clone()) {
(IdxTm::Var(x),
IdxTm::NmSet(ns2)) =>
{
let mut terms = vec![];
for tm2 in ns2.terms.iter() {
nmset_terms_add(
ns2.cons.clone(), &mut terms,
bin_tm(ctx, NmSetTm::Subset(IdxTm::Var(x.clone())),tm2.clone()));
}
IdxTm::NmSet(NmSet{
cons:ns2.cons,
terms:terms
})
},
(IdxTm::NmSet(ns1),
IdxTm::Var(y)) =>
{
let mut terms = vec![];
for tm1 in ns1.terms.iter() {
nmset_terms_add(
ns1.cons.clone(), &mut terms,
bin_tm(ctx, tm1.clone(), NmSetTm::Subset(IdxTm::Var(y.clone()))));
}
IdxTm::NmSet(NmSet{
cons:ns1.cons,
terms:terms
})
},
(IdxTm::NmSet(ns1),
IdxTm::NmSet(ns2)) =>
{
assert_eq!(ns1.cons, ns2.cons);
let mut terms = vec![];
for tm1 in ns1.terms.iter() {
for tm2 in ns2.terms.iter() {
nmset_terms_add(
ns1.cons.clone(), &mut terms,
bin_tm(ctx, tm1.clone(), tm2.clone()));
}
}
IdxTm::NmSet(NmSet{
cons:ns1.cons,
terms:terms
})
},
(i, j) => IdxTm::Bin(Rc::new(i), Rc::new(j))
}
}
IdxTm::App(i1, i2) => {
let i1 = normal_idxtm_rec(ctx, i1);
let i2 = normal_idxtm_rec(ctx, i2);
match (*i1).clone() {
IdxTm::WriteScope => {
match (*i2).clone() {
IdxTm::NmSet(mut ns) => {
let mut terms = vec![];
for t in ns.terms.iter() {
match *t {
NmSetTm::Single(ref n) => {
terms.push( NmSetTm::Single(
normal_nmtm(
ctx, NameTm::App( Rc::new(NameTm::WriteScope), Rc::new(n.clone())
) ) ) )
},
NmSetTm::Subset(ref i) => {
let i = normal_idxtm(
ctx, IdxTm::App(
Rc::new( IdxTm::WriteScope ),
Rc::new(i.clone())));
nmset_terms_add(
ns.cons.clone(),
&mut terms,
NmSetTm::Subset( i )
);
}
}
}
ns.terms = terms;
normal_idxtm(ctx, IdxTm::NmSet(ns))
},
i2 => {
normal_idxtm(ctx, IdxTm::Map(Rc::new(NameTm::WriteScope), Rc::new(i2)))
}
}
},
IdxTm::Lam(x,_gx,i11) => {
let i11 = subst::subst_term_idxtm(Term::IdxTm((*i2).clone()), &x, (*i11).clone());
normal_idxtm(ctx, i11)
}
_ => IdxTm::App(i1, i2)
}
}
IdxTm::Map(n1, i2) => {
let n1 = normal_nmtm_rec(ctx, n1);
let i2 = normal_idxtm_rec(ctx, i2);
match ((*n1).clone(), (*i2).clone()) {
(NameTm::Lam(_,_,_), IdxTm::Var(ref x))
if None != bitype::find_defs_for_idxtm_var(&ctx, &x) =>
{
let xdef = bitype::find_defs_for_idxtm_var(&ctx, &x).unwrap();
match normal_idxtm(ctx, xdef) {
IdxTm::NmSet(ns) => {
let mut terms = vec![];
for t in ns.terms.iter() {
match t {
&NmSetTm::Single(ref n) => {
let tm = normal_idxtm(ctx, IdxTm::Map(n1.clone(), Rc::new(IdxTm::Sing(n.clone()))));
nmset_terms_add(ns.cons.clone(), &mut terms, NmSetTm::Subset(tm))
}
&NmSetTm::Subset(ref i) => {
let tm = normal_idxtm(ctx, IdxTm::Map(n1.clone(), Rc::new(i.clone())));
nmset_terms_add(ns.cons.clone(), &mut terms, NmSetTm::Subset(tm));
}
}
};
IdxTm::NmSet(NmSet{
cons:ns.cons.clone(),
terms:terms,
})
},
_ => {
IdxTm::Map(n1, i2)
}
}
}
(NameTm::Lam(_x,_gx,_n11), IdxTm::NmSet(ns2)) => {
let mut terms = vec![];
for tm2 in ns2.terms.iter() {
use self::NmSetTm::*;
let mapped_tm = match tm2.clone() {
Single(n) => {
Single(normal_nmtm(ctx, NameTm::App(n1.clone(), Rc::new(n.clone()))))
}
Subset(i) => {
Subset(IdxTm::Map(n1.clone(), Rc::new(i)))
}
};
nmset_terms_add(ns2.cons.clone(), &mut terms, mapped_tm)
};
IdxTm::NmSet(NmSet{
cons:ns2.cons,
terms:terms
})
},
(NameTm::WriteScope, IdxTm::NmSet(ns2)) => {
let mut terms = vec![];
for tm2 in ns2.terms.iter() {
use self::NmSetTm::*;
let mapped_tm = match tm2.clone() {
Single(n) => {
Single(normal_nmtm(ctx, NameTm::App(Rc::new(NameTm::WriteScope), Rc::new(n.clone()))))
}
Subset(i) => {
Subset(normal_idxtm(ctx, IdxTm::Map(Rc::new(NameTm::WriteScope), Rc::new(i))))
}
};
nmset_terms_add(ns2.cons.clone(), &mut terms, mapped_tm)
};
IdxTm::NmSet(NmSet{
cons:ns2.cons,
terms:terms
})
},
(n1, i2) => {
IdxTm::Map(Rc::new(n1), Rc::new(i2))
}
}
}
IdxTm::MapStar(n1, i2) => {
let n1 = normal_nmtm_rec(ctx, n1);
let i2 = normal_idxtm_rec(ctx, i2);
match ((*n1).clone(), (*i2).clone()) {
(NameTm::Lam(_,_,_), IdxTm::Var(ref x))
if None != bitype::find_defs_for_idxtm_var(&ctx, &x) =>
{
let xdef = bitype::find_defs_for_idxtm_var(&ctx, &x).unwrap();
match normal_idxtm(ctx, xdef) {
IdxTm::NmSet(ns) => {
let mut terms = vec![];
for t in ns.terms.iter() {
match t {
&NmSetTm::Single(ref n) => {
let tm = normal_idxtm(ctx, IdxTm::MapStar(n1.clone(), Rc::new(IdxTm::Sing(n.clone()))));
nmset_terms_add(ns.cons.clone(), &mut terms, NmSetTm::Subset(tm))
}
&NmSetTm::Subset(ref i) => {
let tm = normal_idxtm(ctx, IdxTm::MapStar(n1.clone(), Rc::new(i.clone())));
nmset_terms_add(ns.cons.clone(), &mut terms, NmSetTm::Subset(tm));
}
}
};
IdxTm::NmSet(NmSet{
cons:ns.cons.clone(),
terms:terms,
})
},
_ => {
IdxTm::MapStar(n1, i2)
}
}
}
(NameTm::Lam(_,_,_), IdxTm::NmSet(ref ns2)) => {
if ns2.terms.len() == 0 {
IdxTm::NmSet(NmSet{
cons:ns2.cons.clone(),
terms:vec![]
})
} else {
let mut terms = vec![];
for tm2 in ns2.terms.iter() {
use self::NmSetTm::*;
let mapped_tm = match tm2.clone() {
Single(n) => {
Subset(IdxTm::MapStar(n1.clone(), Rc::new(IdxTm::Sing(n))))
}
Subset(i) => {
Subset(IdxTm::MapStar(n1.clone(), Rc::new(i)))
}
};
nmset_terms_add(ns2.cons.clone(), &mut terms, mapped_tm)
};
IdxTm::NmSet(NmSet{
cons:ns2.cons.clone(),
terms:terms
})
}
},
(n1, i2) => {
IdxTm::MapStar(Rc::new(n1), Rc::new(i2))
}
}
}
IdxTm::FlatMap(i1, i2) => {
let i1 = normal_idxtm_rec(ctx, i1);
let i2 = normal_idxtm_rec(ctx, i2);
match ((*i1).clone(), (*i2).clone()) {
(IdxTm::Lam(x,_gx,i11), IdxTm::NmSet(ns2)) => {
let mut terms = vec![];
for tm2 in ns2.terms.iter() {
use self::NmSetTm::*;
match tm2.clone() {
Single(n) => {
let i12 = subst::subst_term_idxtm(Term::NmTm(n.clone()), &x, (*i11).clone());
match normal_idxtm(ctx, i12) {
IdxTm::NmSet(mut ns) => {
if ns.cons == None || ns.cons == Some(NmSetCons::Apart) {
terms.append(&mut ns.terms);
ns.cons = Some(NmSetCons::Apart);
} else {
terms.push(Subset(IdxTm::NmSet(ns)))
}
}
i13 => {
nmset_terms_add(ns2.cons.clone(), &mut terms, Subset(i13))
}
}
}
Subset(i) => {
nmset_terms_add(
ns2.cons.clone(),
&mut terms,
NmSetTm::Subset(normal_idxtm(ctx, IdxTm::FlatMap(i1.clone(), Rc::new(i))))
);
}
};
};
IdxTm::NmSet(NmSet{
cons:ns2.cons,
terms:terms
})
},
(IdxTm::Lam(_,_,_), IdxTm::Var(ref x))
if None != bitype::find_defs_for_idxtm_var(&ctx, &x) =>
{
let xdef = bitype::find_defs_for_idxtm_var(&ctx, &x).unwrap();
match normal_idxtm(ctx, xdef) {
IdxTm::NmSet(ns) => {
let mut terms = vec![];
for t in ns.terms.iter() {
match t {
&NmSetTm::Single(ref n) => {
let tm = normal_idxtm(ctx, IdxTm::FlatMap(i1.clone(), Rc::new(IdxTm::Sing(n.clone()))));
nmset_terms_add(ns.cons.clone(), &mut terms, NmSetTm::Subset(tm))
}
&NmSetTm::Subset(ref i) => {
let tm = normal_idxtm(ctx, IdxTm::FlatMap(i1.clone(), Rc::new(i.clone())));
nmset_terms_add(ns.cons.clone(), &mut terms, NmSetTm::Subset(tm));
}
}
};
IdxTm::NmSet(NmSet{
cons:ns.cons.clone(),
terms:terms,
})
},
_ => {
IdxTm::FlatMap(i1, i2)
}
}
}
(IdxTm::Lam(x,gx,body), j) => { match (*body).clone() {
IdxTm::Sing(body_nmtm) => {
normal_idxtm(
ctx,
IdxTm::Map(Rc::new(NameTm::Lam(x,gx,Rc::new(body_nmtm))),
Rc::new(j))
)
},
IdxTm::Apart(body_l, body_r) => {
normal_idxtm(
ctx,
IdxTm::Apart(
Rc::new(normal_idxtm(
ctx,
IdxTm::FlatMap(
Rc::new(IdxTm::Lam(x.clone(), gx.clone(), body_l)),
Rc::new(j.clone())
))),
Rc::new(normal_idxtm(
ctx,
IdxTm::FlatMap(
Rc::new(IdxTm::Lam(x.clone(), gx.clone(), body_r)),
Rc::new(j)
))),
))
},
_ => {
IdxTm::FlatMap(i1, i2)
}
}},
_tm => {
IdxTm::FlatMap(i1, i2)
}
}
},
IdxTm::FlatMapStar(i, j) => {
let i = normal_idxtm_rec(ctx, i);
let j = normal_idxtm_rec(ctx, j);
match ((*i).clone(), (*j).clone()) {
(IdxTm::Lam(_,_,_), IdxTm::Var(ref x))
if None != bitype::find_defs_for_idxtm_var(&ctx, &x) =>
{
let xdef = bitype::find_defs_for_idxtm_var(&ctx, &x).unwrap();
match normal_idxtm(ctx, xdef) {
IdxTm::NmSet(ns) => {
let mut terms = vec![];
for t in ns.terms.iter() {
match t {
&NmSetTm::Single(ref n) => {
let tm = normal_idxtm(ctx, IdxTm::FlatMapStar(i.clone(), Rc::new(IdxTm::Sing(n.clone()))));
nmset_terms_add(
ns.cons.clone(),
&mut terms,
NmSetTm::Subset(tm)
);
}
&NmSetTm::Subset(ref j) => {
let tm = normal_idxtm(ctx, IdxTm::FlatMapStar(i.clone(), Rc::new(j.clone())));
nmset_terms_add(
ns.cons.clone(),
&mut terms,
NmSetTm::Subset(tm)
);
}
}
};
IdxTm::NmSet(NmSet{
cons:ns.cons.clone(),
terms:terms,
})
},
_ => {
IdxTm::FlatMapStar(i, j)
}
}
},
(IdxTm::Lam(x,gx,body),_) => { match (*body).clone() {
IdxTm::Sing(body_nmtm) => {
normal_idxtm(
ctx,
IdxTm::MapStar(Rc::new(NameTm::Lam(x,gx,Rc::new(body_nmtm))), j)
)
},
IdxTm::Apart(body_l, body_r) => {
normal_idxtm(
ctx,
IdxTm::Apart(
Rc::new(normal_idxtm(
ctx,
IdxTm::FlatMapStar(
Rc::new(IdxTm::Lam(x.clone(), gx.clone(), body_l)),
j.clone()
))),
Rc::new(normal_idxtm(
ctx,
IdxTm::FlatMapStar(
Rc::new(IdxTm::Lam(x.clone(), gx.clone(), body_r)), j
))),
))
},
_ => {
IdxTm::FlatMapStar(i, j)
}
}},
(_, _) => {
IdxTm::FlatMapStar(i, j)
}
}
}
i_othercase => i_othercase
}
}
}
pub fn normal_nmtm(ctx:&Ctx, n:NameTm) -> NameTm {
if is_normal_nmtm(ctx, &n) {
return n
} else {
match n {
NameTm::Ident(x) => {
match ctx.lookup_nmtm_def(&x) {
Some(a) => {
normal_nmtm(ctx, a)
},
_ => {
println!("undefined name term: {} in\n{:?}", x, ctx);
NameTm::Ident(x.clone())
}
}
}
NameTm::Bin(n1,n2) => {
let n1 = normal_nmtm_rec(ctx, n1);
let n2 = normal_nmtm_rec(ctx, n2);
match ((*n1).clone(),(*n2).clone()) {
(NameTm::Name(n1),
NameTm::Name(n2)) => {
NameTm::Name(
Name::Bin(Rc::new(n1),
Rc::new(n2)))
},
_ => NameTm::Bin(n1,n2)
}
},
NameTm::App(n1,n2) => {
let n1 = normal_nmtm_rec(ctx, n1);
let n2 = normal_nmtm_rec(ctx, n2);
match ((*n1).clone(), (*n2).clone()) {
(NameTm::Lam(x, _xg, n11), n2) => {
let n12 = subst::subst_nmtm_rec(n2, &x, n11);
normal_nmtm(ctx, (*n12).clone())
},
_ => NameTm::App(n1,n2)
}
},
n_othercase => n_othercase
}
}
}
pub fn normal_nmtm_rec(ctx:&Ctx, n:Rc<NameTm>) -> Rc<NameTm> {
Rc::new(normal_nmtm(ctx, (*n).clone()))
}
pub fn idxtm_of_nmsettms(tms:&NmSetTms) -> IdxTm {
let mut i : IdxTm = IdxTm::Empty;
for t in tms.iter() {
i = IdxTm::Apart(
Rc::new({
match (*t).clone() {
NmSetTm::Single(m) => IdxTm::Sing(m),
NmSetTm::Subset(i) => i.clone()
}
}),
Rc::new(i)
);
}
return i
}
pub fn normal_type(ctx:&Ctx, typ:&Type) -> Type {
match typ {
&Type::Unit |
&Type::Var(_) |
&Type::Sum(_, _) |
&Type::Prod(_, _) |
&Type::Thk(_, _) |
&Type::Ref(_, _) |
&Type::Rec(_, _) |
&Type::Nm(_) |
&Type::NmFn(_) |
&Type::TypeFn(_,_,_)|
&Type::IdxFn(_,_,_) |
&Type::NoParse(_) |
&Type::Exists(_,_,_,_)
=>
typ.clone(),
&Type::Ident(ref ident) => { match ident.as_str() {
"Nat" | "Bool" | "String"
=> { typ.clone() }
_ => { match ctx.lookup_type_def(ident) {
Some(a) => {
if let Type::Ident(_) = a { a.clone() }
else { normal_type(ctx, &a) }
},
_ => {
println!("undefined type: {} in\n{:?}", ident, ctx);
typ.clone()
}
}}
}}
&Type::TypeApp(ref a, ref b) => {
let a = normal_type(ctx, a);
let a = match a {
Type::Rec(_,_) => unroll_type(&a),
_ => a,
};
let b = normal_type(ctx, b);
match a {
Type::TypeFn(ref x, ref _k, ref body) => {
let body = subst::subst_type_type(b,x,(**body).clone());
normal_type(ctx, &body)
},
a => {
println!("sort error: expected TypeFn, not {:?}", a);
typ.clone()
}
}
}
&Type::IdxApp(ref a, ref i) => {
let a = normal_type(ctx, a);
let a = match a {
Type::Rec(_,_) => unroll_type(&a),
_ => a,
};
match a {
Type::IdxFn(ref x, ref _g, ref body) => {
let body = subst::subst_idxtm_type(i.clone(),x,(**body).clone());
normal_type(ctx, &body)
},
a => {
println!("sort error: expected TypeFn, not {:?}", a);
typ.clone()
}
}
}
}
}
pub fn normal_ctype(ctx:&Ctx, ct:CType) -> CType {
match ct {
CType::Lift(a) => {
CType::Lift(normal_type(ctx, &a))
}
CType::Arrow(a, ce) => {
CType::Arrow(normal_type(ctx, &a),
normal_ceffect_rec(ctx, ce))
}
CType::NoParse(s) => CType::NoParse(s)
}
}
pub fn normal_effect(ctx:&Ctx, eff:Effect) -> Effect {
match eff {
Effect::WR(i, j) => {
Effect::WR(normal_idxtm(ctx, i),
normal_idxtm(ctx, j))
},
Effect::NoParse(s) => Effect::NoParse(s)
}
}
pub fn normal_ceffect(ctx:&Ctx, ce:CEffect) -> CEffect {
match ce {
CEffect::Cons(ct, eff) => {
CEffect::Cons(normal_ctype(ctx, ct),
normal_effect(ctx, eff))
}
CEffect::ForallType(y, k, ce) => {
CEffect::ForallType(y, k, normal_ceffect_rec(ctx, ce))
}
CEffect::ForallIdx(y, g, p, ce) => {
CEffect::ForallIdx(y, g,
p.clone(),
normal_ceffect_rec(ctx, ce))
}
CEffect::NoParse(s) => CEffect::NoParse(s)
}
}
pub fn normal_ceffect_rec(ctx:&Ctx, ce:Rc<CEffect>) -> Rc<CEffect> {
Rc::new(normal_ceffect(ctx, (*ce).clone()))
}
pub fn unroll_type(typ:&Type) -> Type {
match typ {
&Type::Rec(ref x, ref a) => {
subst::subst_type_type(typ.clone(), x, (**a).clone())
}
_ => {
typ.clone()
}
}
}