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 dummyArgFunc := &interfaces.ExprAny{} // corresponds to the input func
dummyOutList := &interfaces.ExprAny{} // corresponds to the output list 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 // full function
mapped := make(map[string]interfaces.Expr) mapped := make(map[string]interfaces.Expr)
ordered := []string{inputsName, functionName} ordered := []string{inputsName, functionName}
@@ -105,6 +120,18 @@ func (obj *MapFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, error)
} }
invariants = append(invariants, invar) 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 // generator function
fn := func(fnInvariants []interfaces.Invariant, solved map[interfaces.Expr]*types.Type) ([]interfaces.Invariant, error) { fn := func(fnInvariants []interfaces.Invariant, solved map[interfaces.Expr]*types.Type) ([]interfaces.Invariant, error) {
for _, invariant := range fnInvariants { for _, invariant := range fnInvariants {
@@ -127,9 +154,6 @@ func (obj *MapFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, error)
var invariants []interfaces.Invariant var invariants []interfaces.Invariant
var invar 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 // add the relationship to the returned value
invar = &interfaces.EqualityInvariant{ invar = &interfaces.EqualityInvariant{
Expr1: cfavInvar.Expr, Expr1: cfavInvar.Expr,
@@ -150,6 +174,18 @@ func (obj *MapFunc) Unify(expr interfaces.Expr) ([]interfaces.Invariant, error)
} }
invariants = append(invariants, invar) 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 t1, t2 *types.Type // as seen in our sig's
var foundArgName string = util.NumToAlpha(0) // XXX: is this a hack? 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, Type: t1,
} }
invariants = append(invariants, invar) 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 { if t1 != nil && t2 != nil {
argName := foundArgName // XXX: is this a hack? // TODO: if the argName matters, do it here...
mapped := make(map[string]interfaces.Expr) _ = foundArgName
ordered := []string{argName} //argName := foundArgName // XXX: is this a hack?
mapped[argName] = t1Expr //mapped := make(map[string]interfaces.Expr)
//ordered := []string{argName}
invar = &interfaces.EqualityWrapFuncInvariant{ //mapped[argName] = t1Expr
Expr1: dummyArgFunc, //invar = &interfaces.EqualityWrapFuncInvariant{
Expr2Map: mapped, // Expr1: dummyArgFunc,
Expr2Ord: ordered, // Expr2Map: mapped,
Expr2Out: t2Expr, // Expr2Ord: ordered,
} // Expr2Out: t2Expr,
invariants = append(invariants, invar) //}
//invariants = append(invariants, invar)
} }
// note, currently, we can't learn t2 without t1 // 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, Type: t2,
} }
invariants = append(invariants, invar) 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! // We need to require this knowledge to continue!