             var variables = child.inscope
             variables.insert(v)
             return variables
+        case .aggregate(_, let groups, let aggs):
+            for g in groups {
+                if case .node(.variable(let name)) = g {
+                    variables.insert(name)
+                }
+            }
+            for (_, name) in aggs {
+                variables.insert(name)
+            }
+            return variables
         }
     }
     

            var d = "\(indent)Minus\n"
            d += lhs.serialize(depth: depth+1)
            d += rhs.serialize(depth: depth+1)
            return d
        }
    }

            let parser = NTriplesPatternParser(reader: "")
            guard let pattern = parser.parseTriplePattern(line: rest) else { return nil }
            return .triple(pattern)
        } else if op == "countall" {
            let name = parts[1]
            let groups = parts.suffix(from: 2).map { (name) -> Expression in .node(.variable(name)) }
            guard let child = stack.popLast() else { return nil }
            return .aggregate(child, groups, [(.countAll, name)])
        } else if op == "limit" {
            guard let count = Int(rest) else { return nil }
            guard let child = stack.popLast() else { return nil }
