MCPcopy
hub / github.com/google/mangle / feasibleAlternatives

Method feasibleAlternatives

analysis/validation.go:1107–1286  ·  view source on GitHub ↗

feasibleAlternatives returns feasible alternatives for a subgoal p(e1...eN). We consider a relation type expression (from decl), the given list of arguments, the type assignments to variable symbols, and a type context that collects type variables with associated type constrains. Returns list of alt

(
	pred ast.PredicateSym, relTypeExpr ast.BaseTerm, args []ast.BaseTerm,
	varRanges map[ast.Variable]ast.BaseTerm,
	typeCtx map[ast.Variable]ast.BaseTerm)

Source from the content-addressed store, hash-verified

1105// that collects type variables with associated type constrains.
1106// Returns list of alternatives and list of type contexts with new type constraints.
1107func (bc *BoundsAnalyzer) feasibleAlternatives(
1108 pred ast.PredicateSym, relTypeExpr ast.BaseTerm, args []ast.BaseTerm,
1109 varRanges map[ast.Variable]ast.BaseTerm,
1110 typeCtx map[ast.Variable]ast.BaseTerm) ([]ast.BaseTerm, []map[ast.Variable]ast.BaseTerm, error) {
1111 if pred.Symbol == symbols.ListMember.Symbol {
1112 tpe := boundOfArg(args[1], varRanges, bc.nameTrie)
1113 if tpe == ast.AnyBound {
1114 return []ast.BaseTerm{symbols.NewRelType(ast.AnyBound, symbols.NewListType(ast.AnyBound))}, nil, nil
1115 }
1116 if symbols.IsListTypeExpression(tpe) {
1117 elemTpe, err := symbols.ListTypeArg(tpe)
1118 if err != nil {
1119 return nil, nil, err
1120 }
1121 var bound ast.BaseTerm
1122 if v, ok := args[0].(ast.Variable); ok {
1123 if _, ok := varRanges[v]; ok {
1124 bound = varRanges[v]
1125 } else {
1126 bound = elemTpe // a new variable binding
1127 }
1128 } else {
1129 bound = boundOfArg(args[0], varRanges, bc.nameTrie)
1130 }
1131 // TODO: typing context must give lower bounds as well.
1132 meet := symbols.LowerBound(typeCtx, []ast.BaseTerm{bound, elemTpe})
1133 if !meet.Equals(symbols.EmptyType) {
1134 return []ast.BaseTerm{symbols.NewRelType(meet, tpe)}, []map[ast.Variable]ast.BaseTerm{typeCtx}, nil
1135 }
1136 return nil, nil, fmt.Errorf("pred %v on args %v cannot succeed var ranges %v", pred, args, varRanges)
1137 }
1138 }
1139 if pred.Symbol == symbols.MatchPrefix.Symbol {
1140 tpe := boundOfArg(args[0], varRanges, bc.nameTrie)
1141 prefix := args[1]
1142 meet := symbols.LowerBound(nil /*TODO*/, []ast.BaseTerm{tpe, prefix})
1143 if !meet.Equals(symbols.EmptyType) {
1144 return []ast.BaseTerm{symbols.NewRelType(meet, ast.NameBound)}, []map[ast.Variable]ast.BaseTerm{typeCtx}, nil
1145 }
1146 return nil, nil, fmt.Errorf("pred %v cannot succeed: type %v is incompatible with %v", pred, tpe, prefix)
1147 }
1148
1149 if pred.Symbol == symbols.MatchEntry.Symbol {
1150 tpe := boundOfArg(args[0], varRanges, bc.nameTrie)
1151 if symbols.IsMapTypeExpression(tpe) {
1152 keyType, valTpe, err := symbols.MapTypeArgs(tpe)
1153 if err != nil {
1154 return nil, nil, err
1155 }
1156 var bound ast.BaseTerm
1157 if v, ok := args[1].(ast.Variable); ok {
1158 if _, ok := varRanges[v]; ok {
1159 bound = varRanges[v]
1160 } else {
1161 bound = tpe // a new variable binding
1162 }
1163 } else {
1164 bound = boundOfArg(args[1], varRanges, bc.nameTrie)

Callers 2

getOrInferRelTypesMethod · 0.95

Calls 15

NewRelTypeFunction · 0.92
NewListTypeFunction · 0.92
IsListTypeExpressionFunction · 0.92
ListTypeArgFunction · 0.92
LowerBoundFunction · 0.92
IsMapTypeExpressionFunction · 0.92
MapTypeArgsFunction · 0.92
IsStructTypeExpressionFunction · 0.92
StructTypeFieldFunction · 0.92
RelTypeAlternativesFunction · 0.92
RelTypeArgsFunction · 0.92
AddVarsFunction · 0.92

Tested by

no test coverage detected