package org.basex.query.expr; import static org.basex.query.QueryText.*; import org.basex.query.QueryContext; import org.basex.query.QueryException; import org.basex.query.item.Bln; import org.basex.query.item.SeqType; import org.basex.util.Array; import org.basex.util.InputInfo; import org.basex.util.list.ObjList; /** * Logical expression, extended by {@link And} and {@link Or}. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public abstract class Logical extends Arr { /** * Constructor. * @param ii input info * @param e expression list */ Logical(final InputInfo ii, final Expr[] e) { super(ii, e); type = SeqType.BLN; } @Override public Expr comp(final QueryContext ctx) throws QueryException { for(final Expr e : expr) checkUp(e, ctx); final boolean and = this instanceof And; for(int e = 0; e < expr.length; ++e) { expr[e] = expr[e].comp(ctx).compEbv(ctx); if(!expr[e].isValue()) continue; // atomic items can be pre-evaluated ctx.compInfo(OPTREMOVE, description(), expr[e]); if(expr[e].ebv(ctx, input).bool(input) ^ and) return Bln.get(!and); expr = Array.delete(expr, e--); } return expr.length == 0 ? Bln.get(and) : this; } /** * Flattens nested logical expressions. * @param ctx query context */ final void compFlatten(final QueryContext ctx) { // flatten nested expressions final ObjList<Expr> tmp = new ObjList<Expr>(expr.length); for(final Expr ex : expr) { if(ex.getClass().isInstance(this)) { for(final Expr e : ((Logical) ex).expr) tmp.add(e); ctx.compInfo(OPTFLAT, ex); } else { tmp.add(ex); } } if(expr.length != tmp.size()) expr = tmp.toArray(new Expr[tmp.size()]); } }