EvalReduceFn evaluates a combiner (reduce) function.
(reduceFn ast.ApplyFn, rows []ast.ConstSubstList)
| 1138 | |
| 1139 | // EvalReduceFn evaluates a combiner (reduce) function. |
| 1140 | func EvalReduceFn(reduceFn ast.ApplyFn, rows []ast.ConstSubstList) (ast.Constant, error) { |
| 1141 | distinct := false |
| 1142 | rowsIter := func(v ast.Variable) iter.Seq[ast.Constant] { |
| 1143 | return func(yield func(ast.Constant) bool) { |
| 1144 | for _, subst := range rows { |
| 1145 | if num, ok := subst.Get(v).(ast.Constant); ok { |
| 1146 | if ok := yield(num); !ok { |
| 1147 | return |
| 1148 | } |
| 1149 | } |
| 1150 | } |
| 1151 | } |
| 1152 | } |
| 1153 | |
| 1154 | switch reduceFn.Function.Symbol { |
| 1155 | case symbols.CollectDistinct.Symbol: |
| 1156 | distinct = true |
| 1157 | fallthrough |
| 1158 | case symbols.Collect.Symbol: |
| 1159 | tuples := &ast.ListNil |
| 1160 | |
| 1161 | seen := make(map[uint64][]ast.Constant) |
| 1162 | rowloop: |
| 1163 | for i := len(rows) - 1; i >= 0; i-- { |
| 1164 | subst := rows[i] |
| 1165 | tuple := make([]ast.BaseTerm, 0, len(reduceFn.Args)) |
| 1166 | for _, v := range reduceFn.Args { |
| 1167 | v, err := EvalExpr(v, subst) |
| 1168 | if err != nil { |
| 1169 | continue rowloop |
| 1170 | } |
| 1171 | constant, ok := v.(ast.Constant) |
| 1172 | if !ok { |
| 1173 | continue rowloop |
| 1174 | } |
| 1175 | tuple = append(tuple, constant) |
| 1176 | } |
| 1177 | head, err := EvalApplyFn(ast.ApplyFn{symbols.Tuple, tuple}, subst) |
| 1178 | if err != nil { |
| 1179 | continue rowloop |
| 1180 | } |
| 1181 | if !distinct { |
| 1182 | next := ast.ListCons(&head, tuples) |
| 1183 | tuples = &next |
| 1184 | continue |
| 1185 | } |
| 1186 | |
| 1187 | previousConstants, ok := seen[head.Hash()] |
| 1188 | if ok { |
| 1189 | for _, prev := range previousConstants { |
| 1190 | if prev.Equals(head) { |
| 1191 | continue rowloop |
| 1192 | } |
| 1193 | } |
| 1194 | seen[head.Hash()] = append(seen[head.Hash()], head) |
| 1195 | } else { |
| 1196 | seen[head.Hash()] = []ast.Constant{head} |
| 1197 | } |