text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  const E = require("../expressions/Expressions");
  const Err = require("../util/Errors");
  const Transformation_1 = require("../Transformation");
  /**
   * Evaluator that does not support EXISTS, AGGREGATES or custom Named operators.
   * Evaluates everything sync.
   */
  class SimpleEvaluator {
      constructor(algExpr) {
          this.algExpr = algExpr;
          // tslint:disable-next-line:member-ordering
          this.evaluators = {
              [E.ExpressionType.Term]: this.evalTerm,
              [E.ExpressionType.Variable]: this.evalVariable,
              [E.ExpressionType.Operator]: this.evalOperator,
              [E.ExpressionType.SpecialOperator]: this.evalSpecialOperator,
              [E.ExpressionType.Named]: this.evalNamed,
              [E.ExpressionType.Existence]: this.evalExistence,
              [E.ExpressionType.Aggregate]: this.evalAggregate,
          };
          this.expr = Transformation_1.transformAlgebra(algExpr);
      }
      evaluate(mapping) {
          const result = this.evalRecursive(this.expr, mapping);
          return log(result).toRDF();
      }
      evaluateAsEBV(mapping) {
          const result = this.evalRecursive(this.expr, mapping);
          return log(result).coerceEBV();
      }
      evaluateAsInternal(mapping) {
          return this.evalRecursive(this.expr, mapping);
      }
      evalRecursive(expr, mapping) {
          const evaluator = this.evaluators[expr.expressionType];
          if (!evaluator) {
              throw new Err.InvalidExpressionType(expr);
          }
          return evaluator.bind(this)(expr, mapping);
      }
      evalTerm(expr, mapping) {
          return expr;
      }
      evalVariable(expr, mapping) {
          const term = mapping.get(expr.name);
          if (!term) {
              throw new Err.UnboundVariableError(expr.name, mapping);
          }
          return Transformation_1.transformTerm({
              term,
              type: 'expression',
              expressionType: 'term',
          });
      }
      evalOperator(expr, mapping) {
          const args = expr.args.map((arg) => this.evalRecursive(arg, mapping));
          return expr.apply(args);
      }
      evalSpecialOperator(expr, mapping) {
          const evaluate = this.evalRecursive.bind(this);
          const context = { args: expr.args, mapping, evaluate };
          return expr.applySync(context);
      }
      evalNamed(expr, mapping) {
          const args = expr.args.map((arg) => this.evalRecursive(arg, mapping));
          return expr.apply(args);
      }
      evalExistence(expr, mapping) {
          throw new UnsupportedOperation('EXISTS');
      }
      evalAggregate(expr, mapping) {
          throw new UnsupportedOperation(`aggregate ${expr.name}`);
      }
  }
  exports.SimpleEvaluator = SimpleEvaluator;
  function log(val) {
      // console.log(val);
      return val;
  }
  class UnsupportedOperation extends Error {
      constructor(operation) {
          super(`Operation '${operation}' is unsupported in SimpleEvaluator`);
      }
  }
  exports.UnsupportedOperation = UnsupportedOperation;
  //# sourceMappingURL=SimpleEvalutator.js.map