Process the IsNullExpression object from the QTI Data Model.

@return boolean Whether the sub-expression is considered to be NULL.
@throws \qtism\runtime\expressions\operators\OperatorProcessingException If something goes wrong.
352668
public function process()
    {
        $operands = $this->getOperands();
        $expression = $this->getExpression();

        return new QtiBoolean($operands->containsNull());
    }
618245
public BooleanExpression isNotNull() {
        if (isnotnull == null) {
            isnotnull = Expressions.booleanOperation(Ops.IS_NOT_NULL, mixin);
        }
        return isnotnull;
    }
1152708
public function isNotNull($field)
    {
        if (!($field instanceof ExpressionInterface)) {
            $field = new IdentifierExpression($field);
        }

        return $this->add(new UnaryExpression('IS NOT NULL', $field, UnaryExpression::POSTFIX));
    }
1182957
public function parse()
    {
        // Note: Order is very important here!
        $operators = [
            Expression::OPERATOR_GTE,
            Expression::OPERATOR_LTE,
            Expression::OPERATOR_NOT,
            Expression::OPERATOR_EQ,
            Expression::OPERATOR_GT,
            Expression::OPERATOR_LT
        ];

        foreach ($operators as $operator) {
            $pos = strpos($this->rawExpression, $operator);

            if ($pos) {

                return new Expression(
                    substr($this->rawExpression, 0, $pos),
                    $operator,
                    substr($this->rawExpression, $pos + strlen($operator))
                );
            }
        }

        // Throw an exception if an operator can't be found
        throw new InvalidExpressionException();
    }
325067
public function process()
    {
        $operands = $this->getOperands();

        if (($c = count($operands)) < 2) {
            $msg = "The 'qtism.runtime.expressions.operators.custom.Implode' custom operator takes 2 sub-expressions as parameters, ${c} given.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::NOT_ENOUGH_OPERANDS);
        } elseif ($operands->containsNull() === true) {
            return null;
        } elseif ($operands->exclusivelyString() === false) {
            $msg = "The 'qtism.runtime.expressions.operators.custom.Implode' custom operator only accepts operands with a string baseType.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_BASETYPE);
        } elseif ($operands[0]->getCardinality() !== Cardinality::SINGLE) {
            $msg = "The 'qtism.runtime.expressions.operators.custom.Implode' custom operator only accepts a first operand with single cardinality.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
        } elseif ($operands[1]->getCardinality() !== Cardinality::MULTIPLE && $operands[1]->getCardinality() !== Cardinality::ORDERED) {
            $msg = "The 'qtism.runtime.expressions.operators.custom.Implode' custom operator only accepts a second operand with multiple or ordered cardinality.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
        }

        $glue = $operands[0]->getValue();
        $pieces = $operands[1];

        // Note: implode() is binary-safe \0/!
        $string = implode($glue, $pieces->getArrayCopy());

        return new QtiString($string);
    }
811550
@NonNull
    public Expression isNullOrMissing() {
        return new UnaryExpression(this, UnaryExpression.OpType.Null)
            .or(new UnaryExpression(this, UnaryExpression.OpType.Missing));
    }
1090029
public function process()
    {
        $expr = $this->getExpression();
        $min = $expr->getMin();
        $max = $expr->getMax();

        $state = $this->getState();

        $min = (is_float($min)) ? $min : $state[Utils::sanitizeVariableRef($min)]->getValue();
        $max = (is_float($max)) ? $max : $state[Utils::sanitizeVariableRef($max)]->getValue();

        if (is_float($min) && is_float($max)) {

            if ($min <= $max) {
                return new QtiFloat(($min + lcg_value() * (abs($max - $min))));
            } else {
                $msg = "'min':'${min}' is greater than 'max':'${max}'.";
                throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::LOGIC_ERROR);
            }
        } else {
            $msg = "At least one of the following values is not a float: 'min', 'max'.";
            throw new ExpressionProcessingException($msg, $this, ExpressionProcessingException::WRONG_VARIABLE_BASETYPE);
        }
    }
813746
public function isEmpty(): bool
    {
        return $this->isNull()
            || (is_array($this->value) && count($this->value) === 0)
            || (is_string($this->value) && strlen($this->value) === 0);
    }
532356
public function ConditionalExpression()
    {
        $conditionalTerms = array();
        $conditionalTerms[] = $this->ConditionalTerm();

        while ($this->lexer->isNextToken(Lexer::T_OR)) {
            $this->match(Lexer::T_OR);

            $conditionalTerms[] = $this->ConditionalTerm();
        }

        // Phase 1 AST optimization: Prevent AST\ConditionalExpression
        // if only one AST\ConditionalTerm is defined
        if (count($conditionalTerms) == 1) {
            return $conditionalTerms[0];
        }

        return new AST\ConditionalExpression($conditionalTerms);
    }
387857
public function toBool()
    {
        return (!is_null($this->returnValue)) &&
            (!empty($this->returnValue)) &&
            (!in_array(strtolower($this->returnValue), $this->falseStrings));
    }
1236912
public function process()
    {
        $operands = $this->getOperands();

        if ($operands->containsNull() === true) {
            return null;
        }

        if ($operands->exclusivelySingle() === false) {
            $msg = "The MathOperator operator only accepts operands with a single cardinality.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
        }

        if ($operands->exclusivelyNumeric() === false) {
            $msg = "The MathOperator operator only accepts operands with an integer or float baseType.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_BASETYPE);
        }

        $qtiFuncName = MathFunctions::getNameByConstant($this->getExpression()->getName());
        $methodName = 'process' . ucfirst($qtiFuncName);
        $result = call_user_func_array(array($this, $methodName), array());

        if ($result instanceof QtiFloat && is_nan($result->getValue()) === true) {
            // outside the domain of the function.
            return null;
        } else {
            return $result;
        }
    }
516475
public function QuantifiedExpression()
    {
        $lookaheadType = $this->lexer->lookahead['type'];
        $value         = $this->lexer->lookahead['value'];

        if (! in_array($lookaheadType, [Lexer::T_ALL, Lexer::T_ANY, Lexer::T_SOME], true)) {
            $this->syntaxError('ALL, ANY or SOME');
        }

        $this->match($lookaheadType);
        $this->match(Lexer::T_OPEN_PARENTHESIS);

        $qExpr       = new AST\QuantifiedExpression($this->Subselect());
        $qExpr->type = $value;

        $this->match(Lexer::T_CLOSE_PARENTHESIS);

        return $qExpr;
    }
184547
final public Selector NullPredicate() throws ParseException {
                             boolean not=false; Selector ans;
    ans = FieldRef();
    jj_consume_token(IS);
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case NOT:
      jj_consume_token(NOT);
                                    not = true;
      break;
    default:
      jj_la1[11] = jj_gen;
      ;
    }
    jj_consume_token(NULL);
    ans = new OperatorImpl(Operator.ISNULL, ans);
    if (not) {if (true) return new OperatorImpl(Operator.NOT, ans);}
    else {if (true) return ans;}
    throw new Error("Missing return statement in function");
  }
845630
protected function evaluateUpperBound()
    {
        if (empty($this->upperBound)) {
            return null;
        }

        return $this->executeRule(
            new LessThan($this->getAttribute(), $this->getUpperBound(), $this->isUpperInclusive())
        );
    }
889554
public function process()
    {
        $operands = $this->getOperands();

        if ($operands->containsNull() === true) {
            return null;
        }

        if ($operands->exclusivelySingle() === false) {
            $msg = "The Inside operator only accepts operands with a single cardinality.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
        }

        if ($operands->exclusivelyPoint() === false) {
            $msg = "The Inside operator only accepts operands with a baseType of point.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_BASETYPE);
        }

        $operand = $operands[0];
        $coords = $this->getExpression()->getCoords();

        return new QtiBoolean($coords->inside($operand));
    }
14279
public function process()
    {
        $operands = $this->getOperands();

        if ($operands->containsNull() === true) {
            return null;
        }

        if ($operands->sameBaseType() === false) {
            $msg = "The Member operator only accepts values with the same baseType.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_BASETYPE);
        }

        $operand1 = $operands[0];
        $operand2 = $operands[1];

        // The first expression must have single cardinality.
        if (CommonUtils::inferCardinality($operand1) !== Cardinality::SINGLE) {
            $msg = "The first operand of the Member operator must have a single cardinality.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
        }

        // The second expression must have multiple or ordered cardinality.
        $cardinality = CommonUtils::inferCardinality($operand2);
        if ($cardinality === Cardinality::SINGLE) {
            $operand2 = new MultipleContainer($operand1->getBaseType(), array($operand2));
        } elseif ($cardinality !== Cardinality::MULTIPLE && $cardinality !== Cardinality::ORDERED) {
            $msg = "The second operand of the Member operator must have a single, multiple or ordered cardinality.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
        }

        return new QtiBoolean($operand2->contains($operand1));
    }
1183185
public function process()
    {
        $operands = $this->getOperands();

        if ($operands->containsNull() === true) {
            return null;
        }

        if ($operands->exclusivelyMultipleOrOrdered() === false) {
            $msg = "The StatsOperator operator only accepts operands with a multiple or ordered cardinality.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_CARDINALITY);
        }

        if ($operands->exclusivelyNumeric() === false) {
            $msg = "The StatsOperator operator only accepts operands with a multiple or ordered cardinality.";
            throw new OperatorProcessingException($msg, $this, OperatorProcessingException::WRONG_BASETYPE);
        }

        $qtiFuncName = Statistics::getNameByConstant($this->getExpression()->getName());
        $methodName = 'process' . ucfirst($qtiFuncName);

        return call_user_func_array(array($this, $methodName), array());
    }