60     class ValueLevelVisitor : 
public Visitor<int> {
 
   63         int visitConstant(
const Constant&)
 override {
 
   68         int visitTrue(
const True&)
 override {
 
   73         int visitFalse(
const False&)
 override {
 
   78         int visitTupleElement(
const TupleElement& elem)
 override {
 
   79             return elem.getTupleId();
 
   83         int visitScan(
const Scan&)
 override {
 
   88         int visitIndexScan(
const IndexScan& indexScan)
 override {
 
   90             for (
auto& index : indexScan.getRangePattern().first) {
 
   91                 level = std::max(level, visit(index));
 
   93             for (
auto& index : indexScan.getRangePattern().second) {
 
   94                 level = std::max(level, visit(index));
 
  100         int visitChoice(
const Choice& choice)
 override {
 
  101             return std::max(-1, visit(choice.getCondition()));
 
  105         int visitIndexChoice(
const IndexChoice& indexChoice)
 override {
 
  107             for (
auto& index : indexChoice.getRangePattern().first) {
 
  108                 level = std::max(level, visit(index));
 
  110             for (
auto& index : indexChoice.getRangePattern().second) {
 
  111                 level = std::max(level, visit(index));
 
  113             return std::max(level, visit(indexChoice.getCondition()));
 
  117         int visitAggregate(
const Aggregate& aggregate)
 override {
 
  118             return std::max(visit(aggregate.getExpression()), visit(aggregate.getCondition()));
 
  122         int visitIndexAggregate(
const IndexAggregate& indexAggregate)
 override {
 
  124             for (
auto& index : indexAggregate.getRangePattern().first) {
 
  125                 level = std::max(level, visit(index));
 
  127             for (
auto& index : indexAggregate.getRangePattern().second) {
 
  128                 level = std::max(level, visit(index));
 
  130             level = std::max(visit(indexAggregate.getExpression()), level);
 
  131             return std::max(level, visit(indexAggregate.getCondition()));
 
  135         int visitUnpackRecord(
const UnpackRecord& unpack)
 override {
 
  136             return visit(unpack.getExpression());
 
  140         int visitFilter(
const Filter& 
filter)
 override {
 
  141             return visit(
filter.getCondition());
 
  145         int visitBreak(
const Break& 
b)
 override {
 
  146             return visit(
b.getCondition());
 
  150         int visitProject(
const Project& project)
 override {
 
  152             for (
auto& exp : project.getValues()) {
 
  153                 level = std::max(level, visit(exp));
 
  159         int visitSubroutineReturn(
const SubroutineReturn& ret)
 override {
 
  161             for (
auto& exp : ret.getValues()) {
 
  162                 level = std::max(level, visit(exp));
 
  168         int visitAutoIncrement(
const AutoIncrement&)
 override {
 
  173         int visitUndefValue(
const UndefValue&)
 override {
 
  178         int visitIntrinsicOperator(
const IntrinsicOperator& op)
 override {
 
  180             for (
const auto& arg : op.getArguments()) {
 
  181                 level = std::max(level, visit(arg));
 
  187         int visitPackRecord(
const PackRecord& 
pack)
 override {
 
  189             for (
const auto& arg : 
pack.getArguments()) {
 
  190                 level = std::max(level, visit(arg));
 
  196         int visitSubroutineArgument(
const SubroutineArgument&)
 override {
 
  201         int visitUserDefinedOperator(
const UserDefinedOperator& op)
 override {
 
  203             for (
const auto& arg : op.getArguments()) {
 
  204                 level = std::max(level, visit(arg));
 
  210         int visitConjunction(
const Conjunction& conj)
 override {
 
  211             return std::max(visit(conj.getLHS()), visit(conj.getRHS()));
 
  215         int visitNegation(
const Negation& neg)
 override {
 
  216             return visit(neg.getOperand());
 
  220         int visitConstraint(
const Constraint& binRel)
 override {
 
  221             return std::max(visit(binRel.getLHS()), visit(binRel.getRHS()));
 
  225         int visitExistenceCheck(
const ExistenceCheck& exists)
 override {
 
  227             for (
const auto& cur : exists.getValues()) {
 
  228                 level = std::max(level, visit(cur));
 
  234         int visitProvenanceExistenceCheck(
const ProvenanceExistenceCheck& provExists)
 override {
 
  236             for (
const auto& cur : provExists.getValues()) {
 
  237                 level = std::max(level, visit(cur));
 
  243         int visitEmptinessCheck(
const EmptinessCheck&)
 override {
 
  248         int visitNode(
const Node&)
 override {
 
  249             fatal(
"Node not implemented!");
 
  253     assert((isA<Expression>(node) || isA<Condition>(node) || isA<Operation>(node)) &&
 
  254             "not an expression/condition/operation");
 
  255     return ValueLevelVisitor().visit(node);