Пример #1
0
  // we drop all arguments that are types.  We also drop stars as
  // arguments, for the benefit of Inj.
  public Expr dropAnnos(Context ctxt) {
    int iend = X.length;
    Expr[] X2 = new Expr[iend];
    boolean changed = false;
    int cnt = 0;

    for (int i = 0; i < iend; i++) {
      Expr tmp = X[i];

      if (tmp.isTypeOrKind(ctxt) || tmp.isProof(ctxt) || tmp.construct == STAR || specarg[i]) {
        changed = true;
      } else {
        tmp = tmp.dropAnnos(ctxt);
        X2[cnt] = tmp;
        if (X2[cnt] != X[i]) {
          changed = true;
        }
        cnt++;
      }
    }
    Expr[] X3 = new Expr[cnt];
    System.arraycopy(X2, 0, X3, 0, cnt);

    Expr h = head.dropAnnos(ctxt);

    if (X3.length == 0) {
      return h;
    }

    if (changed || h != head) {
      return new TermApp(h, X3);
    }
    return this;
  }
Пример #2
0
  /**
   * Checks if the predicates are successful for the specified item.
   *
   * @param it item to be checked
   * @param qc query context
   * @return result of check
   * @throws QueryException query exception
   */
  protected final boolean preds(final Item it, final QueryContext qc) throws QueryException {
    if (preds.length == 0) return true;

    // set context value and position
    final Value cv = qc.value;
    try {
      if (qc.scoring) {
        double s = 0;
        for (final Expr p : preds) {
          qc.value = it;
          final Item i = p.test(qc, info);
          if (i == null) return false;
          s += i.score();
        }
        it.score(Scoring.avg(s, preds.length));
      } else {
        for (final Expr p : preds) {
          qc.value = it;
          if (p.test(qc, info) == null) return false;
        }
      }
      return true;
    } finally {
      qc.value = cv;
    }
  }
Пример #3
0
  public Expr dropNoncompArgs(Context ctxt) {
    if (ctxt.getFlag("debug_drop_noncomp")) {
      ctxt.w.println("Dropping non-comp arguments from term-app " + toString(ctxt));
      ctxt.w.flush();
    }
    ArrayList nX = new ArrayList();
    ArrayList no = new ArrayList();
    boolean changed = false;
    Boolean b = new Boolean(false);
    for (int i = 0, iend = X.length; i < iend; i++) {
      if (X[i].isProof(ctxt) || specarg[i]) changed = true;
      else {
        nX.add(X[i]);
        no.add(b);
      }
    }

    Expr ret = this;
    if (changed) {
      if (nX.size() == 0) ret = head;
      else ret = new TermApp(head, Parser.toExprArray(nX), Parser.toBooleanArray(no));
    }

    if (ctxt.getFlag("debug_drop_noncomp")) {
      ctxt.w.println("Returning " + ret.toString(ctxt));
      ctxt.w.flush();
    }

    return ret;
  }
Пример #4
0
  public Expr classify(Context ctxt, int approx, boolean spec) {
    if (ctxt.getFlag("debug_classify_term_apps")) {
      ctxt.w.print("(Classifying ");
      print(ctxt.w, ctxt);
      ctxt.w.println("");
      ctxt.w.flush();
    }
    Expr cl = head.classify(ctxt, approx, spec).defExpandTop(ctxt, false, spec);
    Expr ret = apply_classifier(FUN_TYPE, approx, spec, ctxt, cl, 0);
    FunType ch = (FunType) ((FunType) cl).coalesce(ctxt, spec);
    boolean check_spec_terminates = ctxt.getFlag("check_spec_terminates");
    for (int i = 0; i < X.length; i++) {
      if (ch.owned[i].status == Ownership.SPEC) {
        if (check_spec_terminates) X[i].checkTermination(ctxt);
        specarg[i] = true;
      }
    }
    if (ctxt.getFlag("debug_classify_term_apps")) {
      ctxt.w.println(") Classifier is:");
      ret.print(ctxt.w, ctxt);
      ctxt.w.println("");
      ctxt.w.flush();
    }

    return ret;
  }
Пример #5
0
  @Override
  public final Expr compile(final QueryContext qc, final VarScope scp) throws QueryException {
    if (root != null) root = root.compile(qc, scp);
    // no steps
    if (steps.length == 0) return root == null ? new Context(info) : root;

    final Value init = qc.value, cv = initial(qc);
    final boolean doc = cv != null && cv.type == NodeType.DOC;
    qc.value = cv;
    try {
      final int sl = steps.length;
      for (int s = 0; s < sl; s++) {
        Expr e = steps[s];

        // axis step: if input is a document, its type is temporarily generalized
        final boolean as = e instanceof Step;
        if (as && s == 0 && doc) cv.type = NodeType.NOD;

        e = e.compile(qc, scp);
        if (e.isEmpty()) return optPre(qc);
        steps[s] = e;

        // no axis step: invalidate context value
        if (!as) qc.value = null;
      }
    } finally {
      if (doc) cv.type = NodeType.DOC;
      qc.value = init;
    }
    // optimize path
    return optimize(qc, scp);
  }
Пример #6
0
 @Override
 public boolean has(final Flag flag) {
   for (final Expr pred : preds) {
     if (flag == Flag.FCS && pred.seqType().mayBeNumber() || pred.has(flag)) return true;
   }
   return false;
 }
Пример #7
0
  @Override
  public final Expr optimize(final QueryContext qc, final VarScope scp) throws QueryException {
    final Value v = initial(qc);
    if (v != null && v.isEmpty() || emptyPath(v)) return optPre(qc);

    // merge descendant steps
    Expr e = mergeSteps(qc);
    if (e == this && v != null && v.type == NodeType.DOC) {
      // check index access
      e = index(qc, v);
      // rewrite descendant to child steps
      if (e == this) e = children(qc, v);
    }
    // recompile path if it has changed
    if (e != this) return e.compile(qc, scp);

    // set atomic type for single attribute steps to speed up predicate tests
    if (root == null && steps.length == 1 && steps[0] instanceof Step) {
      final Step curr = (Step) steps[0];
      if (curr.axis == ATTR && curr.test.kind == Kind.URI_NAME) curr.seqType(SeqType.NOD_ZO);
    }

    // choose best path implementation and set type information
    final Path path = get(info, root, steps);
    path.size = path.size(qc);
    path.seqType = SeqType.get(steps[steps.length - 1].seqType().type, size);
    return path;
  }
Пример #8
0
 @Override
 public final boolean has(final Flag flag) {
   // first step or root expression will be used as context
   if (flag == Flag.CTX) return root == null || root.has(flag);
   for (final Expr s : steps) if (s.has(flag)) return true;
   return root != null && root.has(flag);
 }
Пример #9
0
 @Override
 public boolean accept(final ASTVisitor visitor) {
   if (!visitAll(visitor, specs)) return false;
   for (final Expr ng : preExpr) if (!ng.accept(visitor)) return false;
   for (final Var ng : post) if (!visitor.declared(ng)) return false;
   return true;
 }
Пример #10
0
 @Override
 public int exprSize() {
   int sz = 0;
   for (final Expr e : preExpr) sz += e.exprSize();
   for (final Expr e : specs) sz += e.exprSize();
   return sz;
 }
Пример #11
0
 public Eq(Expr e1, Expr e2) {
   super(e1, e2, "==");
   if (e1.getType().isPrimitive() != e2.getType().isPrimitive())
     throw new IllegalArgumentException("type mismatch");
   if (e1.getType().isPrimitive() && e1.getType() != e2.getType())
     throw new IllegalArgumentException("type mismatch");
   // FEATURE: Check if we can compare these classes
 }
Пример #12
0
 @Override
 public void visit(ConstructMultiArrayInstruction insn) {
   Expr[] dimensionExprs = new Expr[insn.getDimensions().size()];
   for (int i = 0; i < dimensionExprs.length; ++i) {
     dimensionExprs[i] = Expr.var(insn.getDimensions().get(i).getIndex());
   }
   assign(Expr.createArray(insn.getItemType(), dimensionExprs), insn.getReceiver());
 }
Пример #13
0
 @Override
 public void visit(BinaryExpr expr) {
   switch (expr.getOperation()) {
     case AND:
     case OR:
       resultExpr = expr;
       return;
     default:
       break;
   }
   expr.getSecondOperand().acceptVisitor(this);
   Expr b = resultExpr;
   if (b instanceof ConstantExpr && expr.getOperation() == BinaryOperation.SUBTRACT) {
     if (tryMakePositive((ConstantExpr) b)) {
       expr.setOperation(BinaryOperation.ADD);
     }
   }
   expr.getFirstOperand().acceptVisitor(this);
   Expr a = resultExpr;
   Expr p = a;
   Expr q = b;
   boolean invert = false;
   if (isZero(p)) {
     Expr tmp = p;
     p = q;
     q = tmp;
     invert = true;
   }
   if (isComparison(p) && isZero(q)) {
     switch (expr.getOperation()) {
       case EQUALS:
       case NOT_EQUALS:
       case LESS:
       case LESS_OR_EQUALS:
       case GREATER:
       case GREATER_OR_EQUALS:
         {
           BinaryExpr comparison = (BinaryExpr) p;
           Expr result =
               BinaryExpr.binary(
                   expr.getOperation(),
                   comparison.getFirstOperand(),
                   comparison.getSecondOperand());
           result.setLocation(comparison.getLocation());
           if (invert) {
             result = ExprOptimizer.invert(result);
           }
           resultExpr = result;
           return;
         }
       default:
         break;
     }
   }
   expr.setFirstOperand(a);
   expr.setSecondOperand(b);
   resultExpr = expr;
 }
Пример #14
0
 @Override
 public void visit(CloneArrayInstruction insn) {
   MethodDescriptor cloneMethodDesc =
       new MethodDescriptor("clone", ValueType.object("java.lang.Object"));
   MethodReference cloneMethod = new MethodReference("java.lang.Object", cloneMethodDesc);
   assign(
       Expr.invoke(cloneMethod, Expr.var(insn.getArray().getIndex()), new Expr[0]),
       insn.getReceiver());
 }
Пример #15
0
 @Override
 public void visit(NewMultiArrayExpr expr) {
   for (int i = 0; i < expr.getDimensions().size(); ++i) {
     Expr dimension = expr.getDimensions().get(i);
     dimension.acceptVisitor(this);
     expr.getDimensions().set(i, resultExpr);
   }
   resultExpr = expr;
 }
Пример #16
0
 @Override
 public void visit(AssignInstruction insn) {
   AssignmentStatement stmt =
       Statement.assign(
           Expr.var(insn.getReceiver().getIndex()), Expr.var(insn.getAssignee().getIndex()));
   stmt.getDebugNames().addAll(insn.getReceiver().getDebugNames());
   stmt.setLocation(currentLocation);
   statements.add(stmt);
 }
Пример #17
0
 @Override
 public void visit(WhileStatement statement) {
   if (statement.getBody().size() == 1 && statement.getBody().get(0) instanceof WhileStatement) {
     WhileStatement innerLoop = (WhileStatement) statement.getBody().get(0);
     BreakToContinueReplacer replacer = new BreakToContinueReplacer(innerLoop, statement);
     replacer.visitSequence(innerLoop.getBody());
     statement.getBody().clear();
     statement.getBody().addAll(innerLoop.getBody());
   }
   List<Statement> statements = processSequence(statement.getBody());
   for (int i = 0; i < statements.size(); ++i) {
     if (statements.get(i) instanceof ContinueStatement) {
       ContinueStatement continueStmt = (ContinueStatement) statements.get(i);
       if (continueStmt.getTarget() == statement) {
         statements.subList(i, statements.size()).clear();
         break;
       }
     }
   }
   statement.getBody().clear();
   statement.getBody().addAll(statements);
   if (statement.getCondition() != null) {
     List<Statement> sequenceBackup = resultSequence;
     resultSequence = new ArrayList<>();
     statement.getCondition().acceptVisitor(this);
     statement.setCondition(resultExpr);
     resultSequence = sequenceBackup;
   }
   while (true) {
     if (!statement.getBody().isEmpty()
         && statement.getBody().get(0) instanceof ConditionalStatement) {
       ConditionalStatement cond = (ConditionalStatement) statement.getBody().get(0);
       if (cond.getConsequent().size() == 1
           && cond.getConsequent().get(0) instanceof BreakStatement) {
         BreakStatement breakStmt = (BreakStatement) cond.getConsequent().get(0);
         if (breakStmt.getTarget() == statement) {
           statement.getBody().remove(0);
           if (statement.getCondition() != null) {
             Expr newCondition =
                 Expr.binary(
                     BinaryOperation.AND,
                     statement.getCondition(),
                     ExprOptimizer.invert(cond.getCondition()));
             newCondition.setLocation(statement.getCondition().getLocation());
             statement.setCondition(newCondition);
           } else {
             statement.setCondition(ExprOptimizer.invert(cond.getCondition()));
           }
           continue;
         }
       }
     }
     break;
   }
   resultStmt = statement;
 }
Пример #18
0
 @Override
 public void visit(PutElementInstruction insn) {
   AssignmentStatement stmt =
       Statement.assign(
           Expr.subscript(
               Expr.var(insn.getArray().getIndex()), Expr.var(insn.getIndex().getIndex())),
           Expr.var(insn.getValue().getIndex()));
   stmt.setLocation(currentLocation);
   statements.add(stmt);
 }
Пример #19
0
 /**
  * Prepares this expression for iterative evaluation. The expression can be iteratively evaluated
  * if no predicate or only the first is positional.
  *
  * @return result of check
  */
 protected final boolean posIterator() {
   // check if first predicate is numeric
   if (preds.length == 1) {
     Expr p = preds[0];
     if (p instanceof Int) p = Pos.get(((Int) p).itr(), info);
     pos = p instanceof Pos ? (Pos) p : null;
     last = p.isFunction(Function.LAST);
     preds[0] = p;
   }
   return pos != null || last;
 }
Пример #20
0
 @Override
 public void visit(PutFieldInstruction insn) {
   Expr right = Expr.var(insn.getValue().getIndex());
   Expr left;
   if (insn.getInstance() != null) {
     left = Expr.qualify(Expr.var(insn.getInstance().getIndex()), insn.getField());
   } else {
     left = Expr.qualify(null, insn.getField());
   }
   AssignmentStatement stmt = Statement.assign(left, right);
   stmt.setLocation(currentLocation);
   statements.add(stmt);
 }
Пример #21
0
 // add selected vars
 public void addQueryExpr(String s) {
   try {
     Expr expr = model.parseExpr(s);
     if (expr instanceof RTVar) {
       addQueryVar(expr);
     } else {
       Expr.List vars = new Expr.List();
       expr.addNamedExpr(vars);
       for (int i = 0; i < vars.size(); i++) addQueryVar(vars.expr(i));
     }
   } catch (Xcept e) {
     // ignore
   }
 }
Пример #22
0
  @Override
  public Expr optimize(final QueryContext ctx, final VarScope scp) throws QueryException {
    if (root instanceof Context) {
      ctx.compInfo(OPTREMCTX);
      root = null;
    }

    for (final Expr e : steps) {
      // check for empty steps
      if (e.isEmpty()) return optPre(null, ctx);
    }

    return this;
  }
Пример #23
0
  /** Type check the expression. */
  public Node typeCheck(TypeChecker tc) throws SemanticException {
    TypeSystem ts = tc.typeSystem();

    if (!ts.isCastValid(expr.type(), castType.type())) {
      throw new SemanticException(
          "Cannot cast the expression of type \""
              + expr.type()
              + "\" to type \""
              + castType.type()
              + "\".",
          position());
    }

    return type(castType.type());
  }
Пример #24
0
 /**
  * Returns the initial context value of a path or {@code null}.
  *
  * @param qc query context (may be @code null)
  * @return root
  */
 private Value initial(final QueryContext qc) {
   // current context value
   final Value v = qc != null ? qc.value : null;
   // no root or context expression: return context
   if (root == null || root instanceof Context) return v;
   // root reference
   if (root instanceof Root) return v != null && v instanceof Item ? Root.root(v) : v;
   // root is value: return root
   if (root.isValue()) return (Value) root;
   // data reference
   final Data d = root.data();
   if (d != null) return new DBNode(d, 0, Data.ELEM);
   // otherwise, return null
   return null;
 }
Пример #25
0
  public App spineForm(Context ctxt, boolean drop_annos, boolean spec, boolean expand_defs) {
    Expr h = head;
    Expr prev = null;
    if (expand_defs) {
      Expr prev2 = null;
      while (h != prev) {
        prev2 = prev;
        prev = h;
        h = h.defExpandOne(ctxt, drop_annos, spec);
      }
      if (prev2 != null) prev = prev2;

      if (h.construct != construct && h.construct != CONST && h.construct != VAR)
        /* we are trying to keep these constructs in the head. */
        h = prev;
    }

    if (ctxt.getFlag("debug_spine_form")) {
      ctxt.w.println("Computing spine form of " + toString(ctxt));
      ctxt.w.println("{");
      ctxt.w.println("Head expands to " + h.toString(ctxt));
      ctxt.w.flush();
    }
    App ret = this;
    if (h.construct == construct) {
      TermApp e = (TermApp) ((TermApp) h).spineForm(ctxt, drop_annos, spec, expand_defs);
      int eXlen = e.X.length;
      int newlen = X.length + eXlen;
      Expr[] X2 = new Expr[newlen];
      boolean[] specarg2 = new boolean[newlen];
      for (int i = 0; i < eXlen; i++) {
        X2[i] = e.X[i];
        specarg2[i] = e.specarg[i];
      }
      for (int i = 0, iend = X.length; i < iend; i++) {
        X2[i + eXlen] = X[i];
        specarg2[i + eXlen] = specarg[i];
      }
      ret = new TermApp(e.head, X2, specarg2);
    } else if (h != head) ret = new TermApp(h, X, specarg);

    if (ctxt.getFlag("debug_spine_form")) {
      ret.print(ctxt.w, ctxt);
      ctxt.w.println("\n}");
      ctxt.w.flush();
    }
    return ret;
  }
Пример #26
0
  public List acceptCFG(CFGBuilder v, List succs) {
    v.visitCFGList(inits, (cond != null ? cond.entry() : body.entry()));

    if (cond != null) {
      if (condIsConstantTrue()) {
        v.visitCFG(cond, body.entry());
      } else {
        v.visitCFG(cond, FlowGraph.EDGE_KEY_TRUE, body.entry(), FlowGraph.EDGE_KEY_FALSE, this);
      }
    }

    v.push(this).visitCFG(body, continueTarget());
    v.visitCFGList(iters, (cond != null ? cond.entry() : body.entry()));

    return succs;
  }
Пример #27
0
  public List throwTypes(TypeSystem ts) {
    if (expr.type().isReference()) {
      return Collections.singletonList(ts.ClassCastException());
    }

    return Collections.EMPTY_LIST;
  }
Пример #28
0
  /**
   * Checks if the path can be rewritten for iterative evaluation.
   *
   * @param root root expression; can be a {@code null} reference
   * @param steps path steps
   * @return result of check
   */
  private static boolean iterative(final Expr root, final Expr... steps) {
    if (root == null || !root.iterable()) return false;

    final int sl = steps.length;
    for (int s = 0; s < sl; ++s) {
      switch (((Step) steps[s]).axis) {
          // reverse axes - don't iterate
        case ANC:
        case ANCORSELF:
        case PREC:
        case PRECSIBL:
          return false;
          // multiple, unsorted results - only iterate at last step,
          // or if last step uses attribute axis
        case DESC:
        case DESCORSELF:
        case FOLL:
        case FOLLSIBL:
          return s + 1 == sl || s + 2 == sl && ((Step) steps[s + 1]).axis == Axis.ATTR;
          // allow iteration for CHILD, ATTR, PARENT and SELF axes
        default:
      }
    }
    return true;
  }
Пример #29
0
  public boolean subtermDefEqNoAnno(Context ctxt, Expr e) {
    // This check is captured below, all arguments always evaluated for a terminating term
    //
    // If it's a TermApp of a constructor, we need to look at all the sub expressions
    // if (head.construct == CONST && ctxt.isTermCtor((Const)head)) {
    //    for (int i = 0; i < X.length; i++)
    //	//if (X[i].defEqNoAnno(ctxt, e))
    //	if (X[i].subtermDefEqNoAnno(ctxt, e))
    //	    return true;
    //    return false;
    // } else {

    // Same as the head?
    // Same as the whole application? ("this")
    if (head.subtermDefEqNoAnno(ctxt, e) || super.subtermDefEqNoAnno(ctxt, e)) return true;
    // In our CBV instantiated function evaluation scheme, all arguments are evaluated, so check
    // equality
    for (int i = 0; i < X.length; i++) if (X[i].subtermDefEqNoAnno(ctxt, e)) return true;
    // Same as any of the spline form TermApp "heads"?
    for (int i = 0; i < X.length; i++) {
      Expr[] newX = new Expr[i + 1];
      for (int j = 0; j <= i; j++) {
        newX[j] = X[j];
      }
      if (e.defEqNoAnno(ctxt, new TermApp(head, newX), true)) return true;
    }
    return false;

    // }
  }
Пример #30
0
 /**
  * Perform type propagation through a given expression, returning the type of value that is
  * returned by evaluating this expression.
  *
  * @param e
  * @param environment
  * @param generics
  * @param context
  * @return
  */
 private SemanticType propagate(
     Expr e,
     HashMap<String, SemanticType> environment,
     HashSet<String> generics,
     WyalFile.Context context) {
   SemanticType t;
   if (e instanceof Expr.Variable) {
     t = propagate((Expr.Variable) e, environment, generics, context);
   } else if (e instanceof Expr.Constant) {
     t = propagate((Expr.Constant) e, environment, generics, context);
   } else if (e instanceof Expr.Unary) {
     t = propagate((Expr.Unary) e, environment, generics, context);
   } else if (e instanceof Expr.Binary) {
     t = propagate((Expr.Binary) e, environment, generics, context);
   } else if (e instanceof Expr.Ternary) {
     t = propagate((Expr.Ternary) e, environment, generics, context);
   } else if (e instanceof Expr.Nary) {
     t = propagate((Expr.Nary) e, environment, generics, context);
   } else if (e instanceof Expr.Quantifier) {
     t = propagate((Expr.Quantifier) e, environment, generics, context);
   } else if (e instanceof Expr.FunCall) {
     t = propagate((Expr.FunCall) e, environment, generics, context);
   } else if (e instanceof Expr.IndexOf) {
     t = propagate((Expr.IndexOf) e, environment, generics, context);
   } else {
     internalFailure("unknown expression encountered (" + e + ")", filename, e);
     return null;
   }
   e.attributes().add(new TypeAttribute(t));
   return returnType(e);
 }