lang: funcs: core: iter: Add map iterator function part3

This flattens the type unification of the map function so that the
solver has more to work with. It's possible that some scenarios might
solve faster, or without recursion, after this improvement.
This commit is contained in:
James Shubin
2021-05-25 00:50:38 -04:00
parent 75d4d767c6
commit 9d5cc07567

View File

@@ -91,6 +91,21 @@ func (obj *MapFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, error)
dummyArgFunc := &interfaces.ExprAny{} // corresponds to the input func
dummyOutList := &interfaces.ExprAny{} // corresponds to the output list
t1Expr := &interfaces.ExprAny{} // corresponds to the t1 type
t2Expr := &interfaces.ExprAny{} // corresponds to the t2 type
invar = &interfaces.EqualityWrapListInvariant{
Expr1: dummyArgList,
Expr2Val: t1Expr,
}
invariants = append(invariants, invar)
invar = &interfaces.EqualityWrapListInvariant{
Expr1: dummyOutList,
Expr2Val: t2Expr,
}
invariants = append(invariants, invar)
// full function
mapped := make(map[string]interfaces.Expr)
ordered := []string{inputsName, functionName}
@@ -105,6 +120,18 @@ func (obj *MapFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, error)
}
invariants = append(invariants, invar)
// relationship between t1 and t2
argName := util.NumToAlpha(0) // XXX: does the arg name matter?
invar = &interfaces.EqualityWrapFuncInvariant{
Expr1: dummyArgFunc,
Expr2Map: map[string]interfaces.Expr{
argName: t1Expr,
},
Expr2Ord: []string{argName},
Expr2Out: t2Expr,
}
invariants = append(invariants, invar)
// generator function
fn := func(fnInvariants []interfaces.Invariant, solved map[interfaces.Expr]*types.Type) ([]interfaces.Invariant, error) {
for _, invariant := range fnInvariants {
@@ -127,9 +154,6 @@ func (obj *MapFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, error)
var invariants []interfaces.Invariant
var invar interfaces.Invariant
t1Expr := &interfaces.ExprAny{} // corresponds to the t1 type
t2Expr := &interfaces.ExprAny{} // corresponds to the t2 type
// add the relationship to the returned value
invar = &interfaces.EqualityInvariant{
Expr1: cfavInvar.Expr,
@@ -150,6 +174,18 @@ func (obj *MapFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, error)
}
invariants = append(invariants, invar)
invar = &interfaces.EqualityWrapListInvariant{
Expr1: cfavInvar.Args[0],
Expr2Val: t1Expr,
}
invariants = append(invariants, invar)
invar = &interfaces.EqualityWrapListInvariant{
Expr1: cfavInvar.Expr,
Expr2Val: t2Expr,
}
invariants = append(invariants, invar)
var t1, t2 *types.Type // as seen in our sig's
var foundArgName string = util.NumToAlpha(0) // XXX: is this a hack?
@@ -264,34 +300,22 @@ func (obj *MapFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, error)
Type: t1,
}
invariants = append(invariants, invar)
invar = &interfaces.EqualityWrapListInvariant{
Expr1: cfavInvar.Args[0],
Expr2Val: t1Expr,
}
invariants = append(invariants, invar)
// we already have the mapping, but add both in
// case we need to solve these from either side
invar = &interfaces.EqualityWrapListInvariant{
Expr1: dummyArgList,
Expr2Val: t1Expr,
}
invariants = append(invariants, invar)
}
if t1 != nil && t2 != nil {
argName := foundArgName // XXX: is this a hack?
mapped := make(map[string]interfaces.Expr)
ordered := []string{argName}
mapped[argName] = t1Expr
invar = &interfaces.EqualityWrapFuncInvariant{
Expr1: dummyArgFunc,
Expr2Map: mapped,
Expr2Ord: ordered,
Expr2Out: t2Expr,
}
invariants = append(invariants, invar)
// TODO: if the argName matters, do it here...
_ = foundArgName
//argName := foundArgName // XXX: is this a hack?
//mapped := make(map[string]interfaces.Expr)
//ordered := []string{argName}
//mapped[argName] = t1Expr
//invar = &interfaces.EqualityWrapFuncInvariant{
// Expr1: dummyArgFunc,
// Expr2Map: mapped,
// Expr2Ord: ordered,
// Expr2Out: t2Expr,
//}
//invariants = append(invariants, invar)
}
// note, currently, we can't learn t2 without t1
@@ -301,19 +325,6 @@ func (obj *MapFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, error)
Type: t2,
}
invariants = append(invariants, invar)
invar = &interfaces.EqualityWrapListInvariant{
Expr1: dummyOutList,
Expr2Val: t2Expr,
}
invariants = append(invariants, invar)
// we already have the mapping, but add both in
// case we need to solve these from either side
invar = &interfaces.EqualityWrapListInvariant{
Expr1: cfavInvar.Expr,
Expr2Val: t2Expr,
}
invariants = append(invariants, invar)
}
// We need to require this knowledge to continue!