public override BoolExpr toZ3Bool(Context ctx)
        {
            var qf = quantified_variables.Select(x => x.toZ3(ctx)).ToArray();

            if (this.quantifier == Quantifier.Exists)
            {
                return(ctx.MkExists(qf, inner.toZ3Bool(ctx)));
            }
            else if (this.quantifier == Quantifier.Forall)
            {
                return(ctx.MkForall(qf, inner.toZ3Bool(ctx)));
            }
            else
            {
                throw new ArgumentException();
            }
        }
        public override BoolExpr toZ3Bool(Context ctx)
        {
            switch (this.logical_operator)
            {
            case LogicalOperator.True:
                return(ctx.MkTrue());

            case LogicalOperator.False:
                return(ctx.MkFalse());

            case LogicalOperator.And:
                return(ctx.MkAnd(new BoolExpr[] { boolean_operand1.toZ3Bool(ctx), boolean_operand2.toZ3Bool(ctx) }));

            case LogicalOperator.Or:
                return(ctx.MkOr(new BoolExpr[] { boolean_operand1.toZ3Bool(ctx), boolean_operand2.toZ3Bool(ctx) }));

            case LogicalOperator.Not:
                return(ctx.MkNot(boolean_operand1.toZ3Bool(ctx)));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }