00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 #include <plang/database.h>
00021 #include <plang/errors.h>
00022 #include "term-priv.h"
00023 #include "database-priv.h"
00024 #include "context-priv.h"
00025 #include <math.h>
00026 #include <string.h>
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029 #include <errno.h>
00030 #include <time.h>
00031 #ifdef HAVE_FENV_H
00032 #include <fenv.h>
00033 #endif
00034 
00134 
00135 p_goal_result p_arith_eval
00136     (p_context *context, p_arith_value *result,
00137      p_term *expr, p_term **error)
00138 {
00139     expr = p_term_deref_member(context, expr);
00140     if (!expr || (expr->header.type & P_TERM_VARIABLE) != 0) {
00141         *error = p_create_instantiation_error(context);
00142         return P_RESULT_ERROR;
00143     }
00144     switch (expr->header.type) {
00145     case P_TERM_ATOM: {
00146         p_db_arith func = p_db_builtin_arith(expr, 0);
00147         if (!func)
00148             break;
00149         return (*func)(context, result, 0, 0, error); }
00150     case P_TERM_FUNCTOR: {
00151         p_arith_value args[2];
00152         p_goal_result goal_result;
00153         p_db_arith func = p_db_builtin_arith
00154             (expr->functor.functor_name, (int)(expr->header.size));
00155         if (!func)
00156             break;
00157         if (expr->header.size == 2) {
00158             goal_result = p_arith_eval
00159                 (context, args, expr->functor.arg[0], error);
00160             if (goal_result != P_RESULT_TRUE)
00161                 return goal_result;
00162             goal_result = p_arith_eval
00163                 (context, args + 1, expr->functor.arg[1], error);
00164             if (goal_result != P_RESULT_TRUE)
00165                 return goal_result;
00166             return (*func)(context, result, args, expr->functor.arg, error);
00167         } else if (expr->header.size == 1) {
00168             goal_result = p_arith_eval
00169                 (context, args, expr->functor.arg[0], error);
00170             if (goal_result != P_RESULT_TRUE)
00171                 return goal_result;
00172             return (*func)(context, result, args, expr->functor.arg, error);
00173         } else {
00174             unsigned int index;
00175             p_arith_value *args = GC_MALLOC
00176                 (sizeof(p_arith_value) * expr->header.size);
00177             if (!args)
00178                 break;
00179             for (index = 0; index < expr->header.size; ++index) {
00180                 goal_result = p_arith_eval
00181                     (context, args + index,
00182                      expr->functor.arg[index], error);
00183                 if (goal_result != P_RESULT_TRUE)
00184                     return goal_result;
00185             }
00186             goal_result = (*func)
00187                 (context, result, args, expr->functor.arg, error);
00188             GC_FREE(args);
00189             return goal_result;
00190         }
00191         break; }
00192     case P_TERM_INTEGER:
00193         result->type = P_TERM_INTEGER;
00194         result->integer_value = p_term_integer_value(expr);
00195         return P_RESULT_TRUE;
00196     case P_TERM_REAL:
00197         result->type = P_TERM_REAL;
00198         result->real_value = p_term_real_value(expr);
00199         return P_RESULT_TRUE;
00200     case P_TERM_STRING:
00201         result->type = P_TERM_STRING;
00202         result->string_value = expr;
00203         return P_RESULT_TRUE;
00204     default: break;
00205     }
00206     *error = p_create_type_error(context, "evaluable", expr);
00207     return P_RESULT_ERROR;
00208 }
00209 
00274 static p_goal_result p_builtin_is
00275     (p_context *context, p_term **args, p_term **error)
00276 {
00277     p_arith_value value;
00278     p_goal_result result;
00279     p_term *value_term;
00280     result = p_arith_eval(context, &value, args[1], error);
00281     if (result != P_RESULT_TRUE)
00282         return result;
00283     switch (value.type) {
00284     case P_TERM_INTEGER:
00285         value_term = p_term_create_integer(context, value.integer_value);
00286         break;
00287     case P_TERM_REAL:
00288         value_term = p_term_create_real(context, value.real_value);
00289         break;
00290     case P_TERM_STRING:
00291         value_term = value.string_value;
00292         break;
00293     default: return P_RESULT_FAIL;
00294     }
00295     if (p_term_unify(context, args[0], value_term, P_BIND_DEFAULT))
00296         return P_RESULT_TRUE;
00297     else
00298         return P_RESULT_FAIL;
00299 }
00300 
00344 static int p_builtin_num_cmp
00345     (p_context *context, p_term **args, p_term **error)
00346 {
00347     p_arith_value value1;
00348     p_arith_value value2;
00349     if (p_arith_eval(context, &value1, args[0], error) != P_RESULT_TRUE)
00350         return -2;
00351     if (p_arith_eval(context, &value2, args[1], error) != P_RESULT_TRUE)
00352         return -2;
00353     if (value1.type == P_TERM_INTEGER) {
00354         if (value2.type == P_TERM_INTEGER) {
00355             if (value1.integer_value < value2.integer_value)
00356                 return -1;
00357             else if (value1.integer_value > value2.integer_value)
00358                 return 1;
00359             else
00360                 return 0;
00361         } else if (value2.type == P_TERM_REAL) {
00362             double val1 = value1.integer_value;
00363             if (val1 < value2.real_value)
00364                 return -1;
00365             else if (val1 > value2.real_value)
00366                 return 1;
00367             else
00368                 return 0;
00369         } else {
00370             *error = p_create_type_error(context, "number", args[1]);
00371             return -2;
00372         }
00373     } else if (value1.type == P_TERM_REAL) {
00374         if (value2.type == P_TERM_REAL) {
00375             if (value1.real_value < value2.real_value)
00376                 return -1;
00377             else if (value1.real_value > value2.real_value)
00378                 return 1;
00379             else
00380                 return 0;
00381         } else if (value2.type == P_TERM_INTEGER) {
00382             double val2 = value2.integer_value;
00383             if (value1.real_value < val2)
00384                 return -1;
00385             else if (value1.real_value > val2)
00386                 return 1;
00387             else
00388                 return 0;
00389         } else {
00390             *error = p_create_type_error(context, "number", args[1]);
00391             return -2;
00392         }
00393     } else if (value1.type == P_TERM_STRING) {
00394         if (value2.type == P_TERM_STRING) {
00395             int cmp = p_term_strcmp
00396                 (value1.string_value, value2.string_value);
00397             if (cmp < 0)
00398                 return -1;
00399             else if (cmp > 0)
00400                 return 1;
00401             else
00402                 return 0;
00403         } else {
00404             *error = p_create_type_error(context, "string", args[1]);
00405             return -2;
00406         }
00407     } else {
00408         *error = p_create_type_error(context, "number", args[0]);
00409         return -2;
00410     }
00411 }
00412 static p_goal_result p_builtin_num_eq
00413     (p_context *context, p_term **args, p_term **error)
00414 {
00415     int cmp = p_builtin_num_cmp(context, args, error);
00416     if (cmp == -2)
00417         return P_RESULT_ERROR;
00418     else if (cmp == 0)
00419         return P_RESULT_TRUE;
00420     else
00421         return P_RESULT_FAIL;
00422 }
00423 
00470 static p_goal_result p_builtin_num_ne
00471     (p_context *context, p_term **args, p_term **error)
00472 {
00473     int cmp = p_builtin_num_cmp(context, args, error);
00474     if (cmp == -2)
00475         return P_RESULT_ERROR;
00476     else if (cmp != 0)
00477         return P_RESULT_TRUE;
00478     else
00479         return P_RESULT_FAIL;
00480 }
00481 
00527 static p_goal_result p_builtin_num_lt
00528     (p_context *context, p_term **args, p_term **error)
00529 {
00530     int cmp = p_builtin_num_cmp(context, args, error);
00531     if (cmp == -2)
00532         return P_RESULT_ERROR;
00533     else if (cmp < 0)
00534         return P_RESULT_TRUE;
00535     else
00536         return P_RESULT_FAIL;
00537 }
00538 
00589 static p_goal_result p_builtin_num_le
00590     (p_context *context, p_term **args, p_term **error)
00591 {
00592     int cmp = p_builtin_num_cmp(context, args, error);
00593     if (cmp == -2)
00594         return P_RESULT_ERROR;
00595     else if (cmp <= 0)
00596         return P_RESULT_TRUE;
00597     else
00598         return P_RESULT_FAIL;
00599 }
00600 
00646 static p_goal_result p_builtin_num_gt
00647     (p_context *context, p_term **args, p_term **error)
00648 {
00649     int cmp = p_builtin_num_cmp(context, args, error);
00650     if (cmp == -2)
00651         return P_RESULT_ERROR;
00652     else if (cmp > 0)
00653         return P_RESULT_TRUE;
00654     else
00655         return P_RESULT_FAIL;
00656 }
00657 
00703 static p_goal_result p_builtin_num_ge
00704     (p_context *context, p_term **args, p_term **error)
00705 {
00706     int cmp = p_builtin_num_cmp(context, args, error);
00707     if (cmp == -2)
00708         return P_RESULT_ERROR;
00709     else if (cmp >= 0)
00710         return P_RESULT_TRUE;
00711     else
00712         return P_RESULT_FAIL;
00713 }
00714 
00755 static p_goal_result p_builtin_atom_name
00756     (p_context *context, p_term **args, p_term **error)
00757 {
00758     p_term *atom = p_term_deref_member(context, args[0]);
00759     p_term *string = p_term_deref_member(context, args[1]);
00760     p_term *result;
00761     if (!atom || !string) {
00762         *error = p_create_instantiation_error(context);
00763         return P_RESULT_ERROR;
00764     }
00765     if (atom->header.type == P_TERM_ATOM) {
00766         result = p_term_create_string_n
00767             (context, p_term_name(atom), p_term_name_length(atom));
00768         if (p_term_unify(context, string, result, P_BIND_DEFAULT))
00769             return P_RESULT_TRUE;
00770         else
00771             return P_RESULT_FAIL;
00772     } else if (atom->header.type & P_TERM_VARIABLE) {
00773         if (string->header.type & P_TERM_VARIABLE) {
00774             *error = p_create_instantiation_error(context);
00775             return P_RESULT_ERROR;
00776         } else if (string->header.type != P_TERM_STRING) {
00777             *error = p_create_type_error(context, "string", string);
00778             return P_RESULT_ERROR;
00779         }
00780         result = p_term_create_atom_n
00781             (context, p_term_name(string), p_term_name_length(string));
00782         if (p_term_unify(context, atom, result, P_BIND_DEFAULT))
00783             return P_RESULT_TRUE;
00784         else
00785             return P_RESULT_FAIL;
00786     } else {
00787         *error = p_create_type_error(context, "atom", atom);
00788         return P_RESULT_ERROR;
00789     }
00790 }
00791 
00843 static p_goal_result p_builtin_fperror
00844     (p_context *context, p_term **args, p_term **error)
00845 {
00846     p_term *type = p_term_deref_member(context, args[0]);
00847     if (!type || (type->header.type & P_TERM_VARIABLE) != 0) {
00848         *error = p_create_instantiation_error(context);
00849         return P_RESULT_ERROR;
00850     }
00851     if (type->header.type != P_TERM_ATOM) {
00852         *error = p_create_type_error(context, "atom", args[0]);
00853         return P_RESULT_ERROR;
00854     }
00855 #if defined(HAVE_FENV_H) && defined(HAVE_FECLEAREXCEPT) && \
00856         defined(HAVE_FETESTEXCEPT)
00857     if (type == p_term_create_atom(context, "clear")) {
00858         feclearexcept(FE_ALL_EXCEPT);
00859         return P_RESULT_TRUE;
00860     } else {
00861         int excepts = 0;
00862         if (type == p_term_create_atom(context, "inexact"))
00863             excepts = FE_INEXACT;
00864         else if (type == p_term_create_atom(context, "overflow"))
00865             excepts = FE_OVERFLOW;
00866         else if (type == p_term_create_atom(context, "undefined"))
00867             excepts = FE_INVALID;
00868         else if (type == p_term_create_atom(context, "underflow"))
00869             excepts = FE_UNDERFLOW;
00870         else if (type == p_term_create_atom(context, "zero_divisor"))
00871             excepts = FE_DIVBYZERO;
00872         else
00873             return P_RESULT_FAIL;
00874         if (fetestexcept(excepts))
00875             return P_RESULT_TRUE;
00876         else
00877             return P_RESULT_FAIL;
00878     }
00879 #else
00880     if (type == p_term_create_atom(context, "clear"))
00881         return P_RESULT_TRUE;
00882     else
00883         return P_RESULT_FAIL;
00884 #endif
00885 }
00886 
00920 static p_goal_result p_builtin_isnan
00921     (p_context *context, p_term **args, p_term **error)
00922 {
00923     p_arith_value value;
00924     p_goal_result result;
00925     result = p_arith_eval(context, &value, args[0], error);
00926     if (result != P_RESULT_TRUE)
00927         return result;
00928     if (value.type == P_TERM_INTEGER) {
00929         return P_RESULT_FAIL;
00930     } else if (value.type == P_TERM_REAL) {
00931         if (isnan(value.real_value))
00932             return P_RESULT_TRUE;
00933         else
00934             return P_RESULT_FAIL;
00935     } else {
00936         *error = p_create_type_error(context, "number", args[0]);
00937         return P_RESULT_ERROR;
00938     }
00939 }
00940 
00978 static p_goal_result p_builtin_isinf
00979     (p_context *context, p_term **args, p_term **error)
00980 {
00981     p_arith_value value;
00982     p_goal_result result;
00983     result = p_arith_eval(context, &value, args[0], error);
00984     if (result != P_RESULT_TRUE)
00985         return result;
00986     if (value.type == P_TERM_INTEGER) {
00987         return P_RESULT_FAIL;
00988     } else if (value.type == P_TERM_REAL) {
00989         if (isinf(value.real_value) != 0)
00990             return P_RESULT_TRUE;
00991         else
00992             return P_RESULT_FAIL;
00993     } else {
00994         *error = p_create_type_error(context, "number", args[0]);
00995         return P_RESULT_ERROR;
00996     }
00997 }
00998 
01039 static p_goal_result p_builtin_randomize_0
01040     (p_context *context, p_term **args, p_term **error)
01041 {
01042     time_t tm;
01043     time(&tm);
01044     context->random_seed = (unsigned int)(tm & 0x7FFFFFFF);
01045     return P_RESULT_TRUE;
01046 }
01047 static p_goal_result p_builtin_randomize_1
01048     (p_context *context, p_term **args, p_term **error)
01049 {
01050     p_term *value = p_term_deref_member(context, args[0]);
01051     if (!value || (value->header.type & P_TERM_VARIABLE) != 0) {
01052         *error = p_create_instantiation_error(context);
01053         return P_RESULT_ERROR;
01054     }
01055     if (value->header.type == P_TERM_INTEGER) {
01056         context->random_seed =
01057             (unsigned int)(p_term_integer_value(value) & 0x7FFFFFFF);
01058     } else if (value->header.type == P_TERM_REAL) {
01059         double v = p_term_real_value(value);
01060         if (v < 0.0)
01061             v = -v;
01062         if (v < 1.0)
01063             v *= 2147483648.0;
01064         context->random_seed = (unsigned int)(((int)v) & 0x7FFFFFFF);
01065     } else {
01066         *error = p_create_type_error(context, "number", value);
01067         return P_RESULT_ERROR;
01068     }
01069     return P_RESULT_TRUE;
01070 }
01071 
01118 static p_goal_result p_arith_add
01119     (p_context *context, p_arith_value *result,
01120      const p_arith_value *values, p_term **args, p_term **error)
01121 {
01122     if (values[0].type == P_TERM_INTEGER) {
01123         if (values[1].type == P_TERM_INTEGER) {
01124             result->type = P_TERM_INTEGER;
01125             result->integer_value =
01126                 values[0].integer_value + values[1].integer_value;
01127             return P_RESULT_TRUE;
01128         } else if (values[1].type == P_TERM_REAL) {
01129             result->type = P_TERM_REAL;
01130             result->real_value =
01131                 values[0].integer_value + values[1].real_value;
01132             return P_RESULT_TRUE;
01133         } else {
01134             *error = p_create_type_error(context, "number", args[1]);
01135             return P_RESULT_ERROR;
01136         }
01137     } else if (values[0].type == P_TERM_REAL) {
01138         if (values[1].type == P_TERM_REAL) {
01139             result->type = P_TERM_REAL;
01140             result->real_value =
01141                 values[0].real_value + values[1].real_value;
01142             return P_RESULT_TRUE;
01143         } else if (values[1].type == P_TERM_INTEGER) {
01144             result->type = P_TERM_REAL;
01145             result->real_value =
01146                 values[0].real_value + values[1].integer_value;
01147             return P_RESULT_TRUE;
01148         } else {
01149             *error = p_create_type_error(context, "number", args[1]);
01150             return P_RESULT_ERROR;
01151         }
01152     } else if (values[0].type == P_TERM_STRING) {
01153         if (values[1].type == P_TERM_STRING) {
01154             result->type = P_TERM_STRING;
01155             result->string_value = p_term_concat_string
01156                 (context, values[0].string_value,
01157                  values[1].string_value);
01158             return P_RESULT_TRUE;
01159         } else {
01160             *error = p_create_type_error(context, "string", args[1]);
01161             return P_RESULT_ERROR;
01162         }
01163     } else {
01164         return P_RESULT_FAIL;
01165     }
01166 }
01167 
01213 static p_goal_result p_arith_neg
01214     (p_context *context, p_arith_value *result,
01215      const p_arith_value *values, p_term **args, p_term **error)
01216 {
01217     if (values[0].type == P_TERM_INTEGER) {
01218         result->type = P_TERM_INTEGER;
01219         result->integer_value = -(values[0].integer_value);
01220         return P_RESULT_TRUE;
01221     } else if (values[0].type == P_TERM_REAL) {
01222         result->type = P_TERM_REAL;
01223         result->real_value = -(values[0].real_value);
01224         return P_RESULT_TRUE;
01225     } else {
01226         *error = p_create_type_error(context, "number", args[0]);
01227         return P_RESULT_ERROR;
01228     }
01229 }
01230 
01271 static p_goal_result p_arith_sub
01272     (p_context *context, p_arith_value *result,
01273      const p_arith_value *values, p_term **args, p_term **error)
01274 {
01275     if (values[0].type == P_TERM_INTEGER) {
01276         if (values[1].type == P_TERM_INTEGER) {
01277             result->type = P_TERM_INTEGER;
01278             result->integer_value =
01279                 values[0].integer_value - values[1].integer_value;
01280             return P_RESULT_TRUE;
01281         } else if (values[1].type == P_TERM_REAL) {
01282             result->type = P_TERM_REAL;
01283             result->real_value =
01284                 values[0].integer_value - values[1].real_value;
01285             return P_RESULT_TRUE;
01286         } else {
01287             *error = p_create_type_error(context, "number", args[1]);
01288             return P_RESULT_ERROR;
01289         }
01290     } else if (values[0].type == P_TERM_REAL) {
01291         if (values[1].type == P_TERM_REAL) {
01292             result->type = P_TERM_REAL;
01293             result->real_value =
01294                 values[0].real_value - values[1].real_value;
01295             return P_RESULT_TRUE;
01296         } else if (values[1].type == P_TERM_INTEGER) {
01297             result->type = P_TERM_REAL;
01298             result->real_value =
01299                 values[0].real_value - values[1].integer_value;
01300             return P_RESULT_TRUE;
01301         } else {
01302             *error = p_create_type_error(context, "number", args[1]);
01303             return P_RESULT_ERROR;
01304         }
01305     } else {
01306         *error = p_create_type_error(context, "number", args[0]);
01307         return P_RESULT_ERROR;
01308     }
01309 }
01310 
01351 static p_goal_result p_arith_mul
01352     (p_context *context, p_arith_value *result,
01353      const p_arith_value *values, p_term **args, p_term **error)
01354 {
01355     if (values[0].type == P_TERM_INTEGER) {
01356         if (values[1].type == P_TERM_INTEGER) {
01357             result->type = P_TERM_INTEGER;
01358             result->integer_value =
01359                 values[0].integer_value * values[1].integer_value;
01360             return P_RESULT_TRUE;
01361         } else if (values[1].type == P_TERM_REAL) {
01362             result->type = P_TERM_REAL;
01363             result->real_value =
01364                 values[0].integer_value * values[1].real_value;
01365             return P_RESULT_TRUE;
01366         } else {
01367             *error = p_create_type_error(context, "number", args[1]);
01368             return P_RESULT_ERROR;
01369         }
01370     } else if (values[0].type == P_TERM_REAL) {
01371         if (values[1].type == P_TERM_REAL) {
01372             result->type = P_TERM_REAL;
01373             result->real_value =
01374                 values[0].real_value * values[1].real_value;
01375             return P_RESULT_TRUE;
01376         } else if (values[1].type == P_TERM_INTEGER) {
01377             result->type = P_TERM_REAL;
01378             result->real_value =
01379                 values[0].real_value * values[1].integer_value;
01380             return P_RESULT_TRUE;
01381         } else {
01382             *error = p_create_type_error(context, "number", args[1]);
01383             return P_RESULT_ERROR;
01384         }
01385     } else {
01386         *error = p_create_type_error(context, "number", args[0]);
01387         return P_RESULT_ERROR;
01388     }
01389 }
01390 
01448 static p_goal_result p_arith_div
01449     (p_context *context, p_arith_value *result,
01450      const p_arith_value *values, p_term **args, p_term **error)
01451 {
01452     if (values[0].type == P_TERM_INTEGER) {
01453         if (values[1].type == P_TERM_INTEGER) {
01454             if (values[1].integer_value != 0) {
01455                 result->type = P_TERM_INTEGER;
01456                 result->integer_value =
01457                     values[0].integer_value / values[1].integer_value;
01458                 return P_RESULT_TRUE;
01459             }
01460         } else if (values[1].type == P_TERM_REAL) {
01461             result->type = P_TERM_REAL;
01462             result->real_value =
01463                 values[0].integer_value / values[1].real_value;
01464             return P_RESULT_TRUE;
01465         } else {
01466             *error = p_create_type_error(context, "number", args[1]);
01467             return P_RESULT_ERROR;
01468         }
01469     } else if (values[0].type == P_TERM_REAL) {
01470         if (values[1].type == P_TERM_REAL) {
01471             result->type = P_TERM_REAL;
01472             result->real_value =
01473                 values[0].real_value / values[1].real_value;
01474             return P_RESULT_TRUE;
01475         } else if (values[1].type == P_TERM_INTEGER) {
01476             result->type = P_TERM_REAL;
01477             result->real_value =
01478                 values[0].real_value / values[1].integer_value;
01479             return P_RESULT_TRUE;
01480         } else {
01481             *error = p_create_type_error(context, "number", args[1]);
01482             return P_RESULT_ERROR;
01483         }
01484     } else {
01485         *error = p_create_type_error(context, "number", args[0]);
01486         return P_RESULT_ERROR;
01487     }
01488     *error = p_create_evaluation_error(context, "zero_divisor");
01489     return P_RESULT_ERROR;
01490 }
01491 
01550 P_INLINE double p_arith_fmod(double x, double y)
01551 {
01552 #if defined(HAVE_FMOD)
01553     return fmod(x, y);
01554 #else
01555     
01556     return 0.0 / 0.0;
01557 #endif
01558 }
01559 static p_goal_result p_arith_mod
01560     (p_context *context, p_arith_value *result,
01561      const p_arith_value *values, p_term **args, p_term **error)
01562 {
01563     if (values[0].type == P_TERM_INTEGER) {
01564         if (values[1].type == P_TERM_INTEGER) {
01565             if (values[1].integer_value != 0) {
01566                 result->type = P_TERM_INTEGER;
01567                 result->integer_value =
01568                     values[0].integer_value % values[1].integer_value;
01569                 return P_RESULT_TRUE;
01570             }
01571         } else if (values[1].type == P_TERM_REAL) {
01572             result->type = P_TERM_REAL;
01573             result->real_value =
01574                 p_arith_fmod(values[0].integer_value,
01575                              values[1].real_value);
01576             return P_RESULT_TRUE;
01577         } else {
01578             *error = p_create_type_error(context, "number", args[1]);
01579             return P_RESULT_ERROR;
01580         }
01581     } else if (values[0].type == P_TERM_REAL) {
01582         if (values[1].type == P_TERM_REAL) {
01583             result->type = P_TERM_REAL;
01584             result->real_value =
01585                 p_arith_fmod(values[0].real_value,
01586                              values[1].real_value);
01587             return P_RESULT_TRUE;
01588         } else if (values[1].type == P_TERM_INTEGER) {
01589             result->type = P_TERM_REAL;
01590             result->real_value =
01591                 p_arith_fmod(values[0].real_value,
01592                              values[1].integer_value);
01593             return P_RESULT_TRUE;
01594         } else {
01595             *error = p_create_type_error(context, "number", args[1]);
01596             return P_RESULT_ERROR;
01597         }
01598     } else {
01599         *error = p_create_type_error(context, "number", args[0]);
01600         return P_RESULT_ERROR;
01601     }
01602     *error = p_create_evaluation_error(context, "zero_divisor");
01603     return P_RESULT_ERROR;
01604 }
01605 
01662 P_INLINE double p_arith_drem(double x, double y)
01663 {
01664 #if defined(HAVE_REMAINDER)
01665     return remainder(x, y);
01666 #elif defined(HAVE_DREM)
01667     return drem(x, y);
01668 #else
01669     if (isnan(x) || isnan(y) || y == 0.0) {
01670         return 0.0 / 0.0;
01671     } else {
01672         double quotient = x / y;
01673         if (quotient >= 0.0)
01674             return x - ceil(quotient) * y;
01675         else
01676             return x - floor(quotient) * y;
01677     }
01678 #endif
01679 }
01680 static p_goal_result p_arith_rem
01681     (p_context *context, p_arith_value *result,
01682      const p_arith_value *values, p_term **args, p_term **error)
01683 {
01684     if (values[0].type == P_TERM_INTEGER) {
01685         if (values[1].type == P_TERM_INTEGER) {
01686             if (values[1].integer_value != 0) {
01687                 result->type = P_TERM_INTEGER;
01688                 result->integer_value =
01689                     values[0].integer_value % values[1].integer_value;
01690                 return P_RESULT_TRUE;
01691             }
01692         } else if (values[1].type == P_TERM_REAL) {
01693             result->type = P_TERM_REAL;
01694             result->real_value =
01695                 p_arith_drem(values[0].integer_value,
01696                              values[1].real_value);
01697             return P_RESULT_TRUE;
01698         } else {
01699             *error = p_create_type_error(context, "number", args[1]);
01700             return P_RESULT_ERROR;
01701         }
01702     } else if (values[0].type == P_TERM_REAL) {
01703         if (values[1].type == P_TERM_REAL) {
01704             result->type = P_TERM_REAL;
01705             result->real_value =
01706                 p_arith_drem(values[0].real_value,
01707                              values[1].real_value);
01708             return P_RESULT_TRUE;
01709         } else if (values[1].type == P_TERM_INTEGER) {
01710             result->type = P_TERM_REAL;
01711             result->real_value =
01712                 p_arith_drem(values[0].real_value,
01713                              values[1].integer_value);
01714             return P_RESULT_TRUE;
01715         } else {
01716             *error = p_create_type_error(context, "number", args[1]);
01717             return P_RESULT_ERROR;
01718         }
01719     } else {
01720         *error = p_create_type_error(context, "number", args[0]);
01721         return P_RESULT_ERROR;
01722     }
01723     *error = p_create_evaluation_error(context, "zero_divisor");
01724     return P_RESULT_ERROR;
01725 }
01726 
01766 static p_goal_result p_arith_and
01767     (p_context *context, p_arith_value *result,
01768      const p_arith_value *values, p_term **args, p_term **error)
01769 {
01770     if (values[0].type == P_TERM_INTEGER) {
01771         if (values[1].type == P_TERM_INTEGER) {
01772             result->type = P_TERM_INTEGER;
01773             result->integer_value =
01774                 values[0].integer_value & values[1].integer_value;
01775             return P_RESULT_TRUE;
01776         } else {
01777             *error = p_create_type_error(context, "integer", args[1]);
01778             return P_RESULT_ERROR;
01779         }
01780     } else {
01781         *error = p_create_type_error(context, "integer", args[0]);
01782         return P_RESULT_ERROR;
01783     }
01784 }
01785 
01825 static p_goal_result p_arith_or
01826     (p_context *context, p_arith_value *result,
01827      const p_arith_value *values, p_term **args, p_term **error)
01828 {
01829     if (values[0].type == P_TERM_INTEGER) {
01830         if (values[1].type == P_TERM_INTEGER) {
01831             result->type = P_TERM_INTEGER;
01832             result->integer_value =
01833                 values[0].integer_value | values[1].integer_value;
01834             return P_RESULT_TRUE;
01835         } else {
01836             *error = p_create_type_error(context, "integer", args[1]);
01837             return P_RESULT_ERROR;
01838         }
01839     } else {
01840         *error = p_create_type_error(context, "integer", args[0]);
01841         return P_RESULT_ERROR;
01842     }
01843 }
01844 
01884 static p_goal_result p_arith_xor
01885     (p_context *context, p_arith_value *result,
01886      const p_arith_value *values, p_term **args, p_term **error)
01887 {
01888     if (values[0].type == P_TERM_INTEGER) {
01889         if (values[1].type == P_TERM_INTEGER) {
01890             result->type = P_TERM_INTEGER;
01891             result->integer_value =
01892                 values[0].integer_value ^ values[1].integer_value;
01893             return P_RESULT_TRUE;
01894         } else {
01895             *error = p_create_type_error(context, "integer", args[1]);
01896             return P_RESULT_ERROR;
01897         }
01898     } else {
01899         *error = p_create_type_error(context, "integer", args[0]);
01900         return P_RESULT_ERROR;
01901     }
01902 }
01903 
01942 static p_goal_result p_arith_not
01943     (p_context *context, p_arith_value *result,
01944      const p_arith_value *values, p_term **args, p_term **error)
01945 {
01946     if (values[0].type == P_TERM_INTEGER) {
01947         result->type = P_TERM_INTEGER;
01948         result->integer_value = ~(values[0].integer_value);
01949         return P_RESULT_TRUE;
01950     } else {
01951         *error = p_create_type_error(context, "integer", args[0]);
01952         return P_RESULT_ERROR;
01953     }
01954 }
01955 
01996 static p_goal_result p_arith_lshift
01997     (p_context *context, p_arith_value *result,
01998      const p_arith_value *values, p_term **args, p_term **error)
01999 {
02000     if (values[0].type == P_TERM_INTEGER) {
02001         if (values[1].type == P_TERM_INTEGER) {
02002             result->type = P_TERM_INTEGER;
02003             result->integer_value =
02004                 values[0].integer_value <<
02005                     (values[1].integer_value & 31);
02006             return P_RESULT_TRUE;
02007         } else {
02008             *error = p_create_type_error(context, "integer", args[1]);
02009             return P_RESULT_ERROR;
02010         }
02011     } else {
02012         *error = p_create_type_error(context, "integer", args[0]);
02013         return P_RESULT_ERROR;
02014     }
02015 }
02016 
02063 static p_goal_result p_arith_rshift
02064     (p_context *context, p_arith_value *result,
02065      const p_arith_value *values, p_term **args, p_term **error)
02066 {
02067     if (values[0].type == P_TERM_INTEGER) {
02068         if (values[1].type == P_TERM_INTEGER) {
02069             result->type = P_TERM_INTEGER;
02070             result->integer_value =
02071                 values[0].integer_value >>
02072                     (values[1].integer_value & 31);
02073             return P_RESULT_TRUE;
02074         } else {
02075             *error = p_create_type_error(context, "integer", args[1]);
02076             return P_RESULT_ERROR;
02077         }
02078     } else {
02079         *error = p_create_type_error(context, "integer", args[0]);
02080         return P_RESULT_ERROR;
02081     }
02082 }
02083 
02123 static p_goal_result p_arith_rushift
02124     (p_context *context, p_arith_value *result,
02125      const p_arith_value *values, p_term **args, p_term **error)
02126 {
02127     if (values[0].type == P_TERM_INTEGER) {
02128         if (values[1].type == P_TERM_INTEGER) {
02129             result->type = P_TERM_INTEGER;
02130             result->integer_value =
02131                 (int)(((unsigned int)(values[0].integer_value)) >>
02132                             (values[1].integer_value & 31));
02133             return P_RESULT_TRUE;
02134         } else {
02135             *error = p_create_type_error(context, "integer", args[1]);
02136             return P_RESULT_ERROR;
02137         }
02138     } else {
02139         *error = p_create_type_error(context, "integer", args[0]);
02140         return P_RESULT_ERROR;
02141     }
02142 }
02143 
02181 static p_goal_result p_arith_abs
02182     (p_context *context, p_arith_value *result,
02183      const p_arith_value *values, p_term **args, p_term **error)
02184 {
02185     if (values[0].type == P_TERM_INTEGER) {
02186         result->type = P_TERM_INTEGER;
02187         if (values[0].integer_value == (int)(-0x7fffffff - 1)) {
02188             *error = p_create_evaluation_error(context, "int_overflow");
02189             return P_RESULT_ERROR;
02190         } else if (values[0].integer_value < 0) {
02191             result->integer_value = -(values[0].integer_value);
02192         } else {
02193             result->integer_value = values[0].integer_value;
02194         }
02195         return P_RESULT_TRUE;
02196     } else if (values[0].type == P_TERM_REAL) {
02197         result->type = P_TERM_REAL;
02198         result->real_value = fabs(values[0].real_value);
02199         return P_RESULT_TRUE;
02200     } else {
02201         *error = p_create_type_error(context, "number", args[0]);
02202         return P_RESULT_ERROR;
02203     }
02204 }
02205 
02241 static p_goal_result p_arith_acos
02242     (p_context *context, p_arith_value *result,
02243      const p_arith_value *values, p_term **args, p_term **error)
02244 {
02245     if (values[0].type == P_TERM_INTEGER) {
02246         result->type = P_TERM_REAL;
02247         result->real_value = acos((double)(values[0].integer_value));
02248         return P_RESULT_TRUE;
02249     } else if (values[0].type == P_TERM_REAL) {
02250         result->type = P_TERM_REAL;
02251         result->real_value = acos(values[0].real_value);
02252         return P_RESULT_TRUE;
02253     } else {
02254         *error = p_create_type_error(context, "number", args[0]);
02255         return P_RESULT_ERROR;
02256     }
02257 }
02258 
02294 static p_goal_result p_arith_asin
02295     (p_context *context, p_arith_value *result,
02296      const p_arith_value *values, p_term **args, p_term **error)
02297 {
02298     if (values[0].type == P_TERM_INTEGER) {
02299         result->type = P_TERM_REAL;
02300         result->real_value = asin((double)(values[0].integer_value));
02301         return P_RESULT_TRUE;
02302     } else if (values[0].type == P_TERM_REAL) {
02303         result->type = P_TERM_REAL;
02304         result->real_value = asin(values[0].real_value);
02305         return P_RESULT_TRUE;
02306     } else {
02307         *error = p_create_type_error(context, "number", args[0]);
02308         return P_RESULT_ERROR;
02309     }
02310 }
02311 
02350 static p_goal_result p_arith_atan
02351     (p_context *context, p_arith_value *result,
02352      const p_arith_value *values, p_term **args, p_term **error)
02353 {
02354     if (values[0].type == P_TERM_INTEGER) {
02355         result->type = P_TERM_REAL;
02356         result->real_value = atan((double)(values[0].integer_value));
02357         return P_RESULT_TRUE;
02358     } else if (values[0].type == P_TERM_REAL) {
02359         result->type = P_TERM_REAL;
02360         result->real_value = atan(values[0].real_value);
02361         return P_RESULT_TRUE;
02362     } else {
02363         *error = p_create_type_error(context, "number", args[0]);
02364         return P_RESULT_ERROR;
02365     }
02366 }
02367 
02409 static p_goal_result p_arith_atan2
02410     (p_context *context, p_arith_value *result,
02411      const p_arith_value *values, p_term **args, p_term **error)
02412 {
02413     if (values[0].type == P_TERM_INTEGER) {
02414         if (values[1].type == P_TERM_INTEGER) {
02415             result->type = P_TERM_REAL;
02416             result->real_value =
02417                 atan2(values[0].integer_value, values[1].integer_value);
02418             return P_RESULT_TRUE;
02419         } else if (values[1].type == P_TERM_REAL) {
02420             result->type = P_TERM_REAL;
02421             result->real_value =
02422                 atan2(values[0].integer_value, values[1].real_value);
02423             return P_RESULT_TRUE;
02424         } else {
02425             *error = p_create_type_error(context, "number", args[1]);
02426             return P_RESULT_ERROR;
02427         }
02428     } else if (values[0].type == P_TERM_REAL) {
02429         if (values[1].type == P_TERM_REAL) {
02430             result->type = P_TERM_REAL;
02431             result->real_value =
02432                 atan2(values[0].real_value, values[1].real_value);
02433             return P_RESULT_TRUE;
02434         } else if (values[1].type == P_TERM_INTEGER) {
02435             result->type = P_TERM_REAL;
02436             result->real_value =
02437                 atan2(values[0].real_value, values[1].integer_value);
02438             return P_RESULT_TRUE;
02439         } else {
02440             *error = p_create_type_error(context, "number", args[1]);
02441             return P_RESULT_ERROR;
02442         }
02443     } else {
02444         *error = p_create_type_error(context, "number", args[0]);
02445         return P_RESULT_ERROR;
02446     }
02447 }
02448 
02491 static p_goal_result p_arith_ceil
02492     (p_context *context, p_arith_value *result,
02493      const p_arith_value *values, p_term **args, p_term **error)
02494 {
02495     if (values[0].type == P_TERM_INTEGER) {
02496         result->type = P_TERM_INTEGER;
02497         result->integer_value = values[0].integer_value;
02498         return P_RESULT_TRUE;
02499     } else if (values[0].type == P_TERM_REAL) {
02500         result->type = P_TERM_REAL;
02501         result->real_value = ceil(values[0].real_value);
02502         return P_RESULT_TRUE;
02503     } else {
02504         *error = p_create_type_error(context, "number", args[0]);
02505         return P_RESULT_ERROR;
02506     }
02507 }
02508 
02547 static p_goal_result p_arith_byte
02548     (p_context *context, p_arith_value *result,
02549      const p_arith_value *values, p_term **args, p_term **error)
02550 {
02551     if (values[0].type == P_TERM_STRING) {
02552         if (values[1].type == P_TERM_INTEGER) {
02553             int index = values[1].integer_value;
02554             if (index >= 0 &&
02555                     index < (int)(values[0].string_value->header.size)) {
02556                 result->type = P_TERM_INTEGER;
02557                 result->integer_value =
02558                     (int)((p_term_name(values[0].string_value))[index]
02559                             & 0xFF);
02560                 return P_RESULT_TRUE;
02561             } else {
02562                 *error = p_create_domain_error
02563                     (context, "string_index", args[1]);
02564                 return P_RESULT_ERROR;
02565             }
02566         } else {
02567             *error = p_create_type_error(context, "integer", args[1]);
02568             return P_RESULT_ERROR;
02569         }
02570     } else {
02571         *error = p_create_type_error(context, "string", args[0]);
02572         return P_RESULT_ERROR;
02573     }
02574 }
02575 
02610 static p_goal_result p_arith_byte_to_string
02611     (p_context *context, p_arith_value *result,
02612      const p_arith_value *values, p_term **args, p_term **error)
02613 {
02614     if (values[0].type == P_TERM_INTEGER) {
02615         int ch = values[0].integer_value;
02616         if (ch >= 0 && ch <= 255) {
02617             char str[1];
02618             str[0] = (char)ch;
02619             result->type = P_TERM_STRING;
02620             result->string_value =
02621                 p_term_create_string_n(context, str, 1);
02622             return P_RESULT_TRUE;
02623         } else {
02624             *error = p_create_type_error(context, "byte", args[0]);
02625             return P_RESULT_ERROR;
02626         }
02627     } else {
02628         *error = p_create_type_error(context, "integer", args[0]);
02629         return P_RESULT_ERROR;
02630     }
02631 }
02632 
02674 static p_goal_result p_arith_char
02675     (p_context *context, p_arith_value *result,
02676      const p_arith_value *values, p_term **args, p_term **error)
02677 {
02678     if (values[0].type == P_TERM_STRING) {
02679         if (values[1].type == P_TERM_INTEGER) {
02680             int index = values[1].integer_value;
02681             const char *str = p_term_name(values[0].string_value);
02682             size_t len = p_term_name_length(values[0].string_value);
02683             size_t size;
02684             int ch;
02685             while (index > 0 && len > 0) {
02686                 ch = _p_term_next_utf8(str, len, &size);
02687                 str += size;
02688                 len -= size;
02689                 --index;
02690             }
02691             if (index == 0 && len > 0) {
02692                 ch = _p_term_next_utf8(str, len, &size);
02693                 result->type = P_TERM_INTEGER;
02694                 result->integer_value = ch;
02695                 return P_RESULT_TRUE;
02696             } else {
02697                 *error = p_create_domain_error
02698                     (context, "string_index", args[1]);
02699                 return P_RESULT_ERROR;
02700             }
02701         } else {
02702             *error = p_create_type_error(context, "integer", args[1]);
02703             return P_RESULT_ERROR;
02704         }
02705     } else {
02706         *error = p_create_type_error(context, "string", args[0]);
02707         return P_RESULT_ERROR;
02708     }
02709 }
02710 
02745 static p_goal_result p_arith_char_to_string
02746     (p_context *context, p_arith_value *result,
02747      const p_arith_value *values, p_term **args, p_term **error)
02748 {
02749     if (values[0].type == P_TERM_INTEGER) {
02750         int ch = values[0].integer_value;
02751         if (ch >= 0 && ch <= 0x10FFFF) {
02752             char str[4];
02753             size_t len;
02754             if (ch < 0x80) {
02755                 str[0] = (char)ch;
02756                 len = 1;
02757             } else if (ch < (1 << (5 + 6))) {
02758                 str[0] = (char)(0xC0 | (ch >> 6));
02759                 str[1] = (char)(0x80 | (ch & 0x3F));
02760                 len = 2;
02761             } else if (ch < (1 << (4 + 6 + 6))) {
02762                 str[0] = (char)(0xE0 | (ch >> 12));
02763                 str[1] = (char)(0x80 | ((ch >> 6) & 0x3F));
02764                 str[2] = (char)(0x80 | (ch & 0x3F));
02765                 len = 3;
02766             } else {
02767                 str[0] = (char)(0xF0 | (ch >> 18));
02768                 str[1] = (char)(0x80 | ((ch >> 12) & 0x3F));
02769                 str[2] = (char)(0x80 | ((ch >> 6) & 0x3F));
02770                 str[3] = (char)(0x80 | (ch & 0x3F));
02771                 len = 4;
02772             }
02773             result->type = P_TERM_STRING;
02774             result->string_value =
02775                 p_term_create_string_n(context, str, len);
02776             return P_RESULT_TRUE;
02777         } else {
02778             *error = p_create_representation_error
02779                 (context, "character_code");
02780             return P_RESULT_ERROR;
02781         }
02782     } else {
02783         *error = p_create_type_error(context, "integer", args[0]);
02784         return P_RESULT_ERROR;
02785     }
02786 }
02787 
02827 static p_goal_result p_arith_cos
02828     (p_context *context, p_arith_value *result,
02829      const p_arith_value *values, p_term **args, p_term **error)
02830 {
02831     if (values[0].type == P_TERM_INTEGER) {
02832         result->type = P_TERM_REAL;
02833         result->real_value = cos((double)(values[0].integer_value));
02834         return P_RESULT_TRUE;
02835     } else if (values[0].type == P_TERM_REAL) {
02836         result->type = P_TERM_REAL;
02837         result->real_value = cos(values[0].real_value);
02838         return P_RESULT_TRUE;
02839     } else {
02840         *error = p_create_type_error(context, "number", args[0]);
02841         return P_RESULT_ERROR;
02842     }
02843 }
02844 
02884 static p_goal_result p_arith_exp
02885     (p_context *context, p_arith_value *result,
02886      const p_arith_value *values, p_term **args, p_term **error)
02887 {
02888     if (values[0].type == P_TERM_INTEGER) {
02889         result->type = P_TERM_REAL;
02890         result->real_value = exp((double)(values[0].integer_value));
02891         return P_RESULT_TRUE;
02892     } else if (values[0].type == P_TERM_REAL) {
02893         result->type = P_TERM_REAL;
02894         result->real_value = exp(values[0].real_value);
02895         return P_RESULT_TRUE;
02896     } else {
02897         *error = p_create_type_error(context, "number", args[0]);
02898         return P_RESULT_ERROR;
02899     }
02900 }
02901 
02925 static p_goal_result p_arith_e
02926     (p_context *context, p_arith_value *result,
02927      const p_arith_value *values, p_term **args, p_term **error)
02928 {
02929     result->type = P_TERM_REAL;
02930     result->real_value = 2.7182818284590452354;
02931     return P_RESULT_TRUE;
02932 }
02933 
02965 static p_goal_result p_arith_float
02966     (p_context *context, p_arith_value *result,
02967      const p_arith_value *values, p_term **args, p_term **error)
02968 {
02969     if (values[0].type == P_TERM_INTEGER) {
02970         result->type = P_TERM_REAL;
02971         result->real_value = values[0].integer_value;
02972         return P_RESULT_TRUE;
02973     } else if (values[0].type == P_TERM_REAL) {
02974         result->type = P_TERM_REAL;
02975         result->real_value = values[0].real_value;
02976         return P_RESULT_TRUE;
02977     } else if (values[0].type == P_TERM_STRING) {
02978         const char *str = p_term_name(values[0].string_value);
02979         char *endptr;
02980         double val;
02981         errno = 0;
02982         val = strtod(str, &endptr);
02983         if (errno == ERANGE || endptr == str) {
02984             
02985             *error = p_create_type_error(context, "number", args[0]);
02986             return P_RESULT_ERROR;
02987         }
02988         while (*endptr == ' ' || *endptr == '\t' ||
02989                *endptr == '\r' || *endptr == '\n')
02990             ++endptr;
02991         if (*endptr != '\0') {
02992             
02993             *error = p_create_type_error(context, "number", args[0]);
02994             return P_RESULT_ERROR;
02995         }
02996         result->type = P_TERM_REAL;
02997         result->real_value = val;
02998         return P_RESULT_TRUE;
02999     } else {
03000         *error = p_create_type_error(context, "number", args[0]);
03001         return P_RESULT_ERROR;
03002     }
03003 }
03004 
03042 static p_goal_result p_arith_float_fractional_part
03043     (p_context *context, p_arith_value *result,
03044      const p_arith_value *values, p_term **args, p_term **error)
03045 {
03046     if (values[0].type == P_TERM_INTEGER) {
03047         result->type = P_TERM_INTEGER;
03048         result->integer_value = 0;
03049         return P_RESULT_TRUE;
03050     } else if (values[0].type == P_TERM_REAL) {
03051         double ipart;
03052         result->type = P_TERM_REAL;
03053         result->real_value = modf(values[0].real_value, &ipart);
03054         return P_RESULT_TRUE;
03055     } else {
03056         *error = p_create_type_error(context, "number", args[0]);
03057         return P_RESULT_ERROR;
03058     }
03059 }
03060 
03098 static p_goal_result p_arith_float_integer_part
03099     (p_context *context, p_arith_value *result,
03100      const p_arith_value *values, p_term **args, p_term **error)
03101 {
03102     if (values[0].type == P_TERM_INTEGER) {
03103         result->type = P_TERM_INTEGER;
03104         result->integer_value = values[0].integer_value;
03105         return P_RESULT_TRUE;
03106     } else if (values[0].type == P_TERM_REAL) {
03107         result->type = P_TERM_REAL;
03108         modf(values[0].real_value, &(result->real_value));
03109         return P_RESULT_TRUE;
03110     } else {
03111         *error = p_create_type_error(context, "number", args[0]);
03112         return P_RESULT_ERROR;
03113     }
03114 }
03115 
03154 static p_goal_result p_arith_floor
03155     (p_context *context, p_arith_value *result,
03156      const p_arith_value *values, p_term **args, p_term **error)
03157 {
03158     if (values[0].type == P_TERM_INTEGER) {
03159         result->type = P_TERM_INTEGER;
03160         result->integer_value = values[0].integer_value;
03161         return P_RESULT_TRUE;
03162     } else if (values[0].type == P_TERM_REAL) {
03163         result->type = P_TERM_REAL;
03164         result->real_value = floor(values[0].real_value);
03165         return P_RESULT_TRUE;
03166     } else {
03167         *error = p_create_type_error(context, "number", args[0]);
03168         return P_RESULT_ERROR;
03169     }
03170 }
03171 
03197 static p_goal_result p_arith_inf
03198     (p_context *context, p_arith_value *result,
03199      const p_arith_value *values, p_term **args, p_term **error)
03200 {
03201     result->type = P_TERM_REAL;
03202     result->real_value = 1.0 / 0.0;
03203     return P_RESULT_TRUE;
03204 }
03205 
03252 static p_goal_result p_arith_integer
03253     (p_context *context, p_arith_value *result,
03254      const p_arith_value *values, p_term **args, p_term **error)
03255 {
03256     if (values[0].type == P_TERM_INTEGER) {
03257         result->type = P_TERM_INTEGER;
03258         result->integer_value = values[0].integer_value;
03259         return P_RESULT_TRUE;
03260     } else if (values[0].type == P_TERM_REAL) {
03261         if (values[0].real_value >= 2147483648.0 ||
03262                 values[0].real_value <= -2147483649.0) {
03263             *error = p_create_evaluation_error(context, "int_overflow");
03264             return P_RESULT_ERROR;
03265         }
03266         result->type = P_TERM_INTEGER;
03267         result->integer_value = (int)(values[0].real_value);
03268         return P_RESULT_TRUE;
03269     } else if (values[0].type == P_TERM_STRING) {
03270         const char *str = p_term_name(values[0].string_value);
03271         char *endptr;
03272         long val;
03273         errno = 0;
03274         val = strtol(str, &endptr, 0);
03275         if (errno == ERANGE) {
03276             
03277             *error = p_create_evaluation_error(context, "int_overflow");
03278             return P_RESULT_ERROR;
03279         } else if (endptr == str) {
03280             
03281             *error = p_create_type_error(context, "integer", args[0]);
03282             return P_RESULT_ERROR;
03283         }
03284         while (*endptr == ' ' || *endptr == '\t' ||
03285                *endptr == '\r' || *endptr == '\n')
03286             ++endptr;
03287         if (*endptr != '\0') {
03288             
03289             *error = p_create_type_error(context, "integer", args[0]);
03290             return P_RESULT_ERROR;
03291         }
03292         if (val != (int)val) {
03293             
03294             *error = p_create_evaluation_error(context, "int_overflow");
03295             return P_RESULT_ERROR;
03296         }
03297         result->type = P_TERM_INTEGER;
03298         result->integer_value = (int)val;
03299         return P_RESULT_TRUE;
03300     } else {
03301         *error = p_create_type_error(context, "integer", args[0]);
03302         return P_RESULT_ERROR;
03303     }
03304 }
03305 
03347 static p_term *p_arith_mid
03348     (p_context *context, p_term *str, unsigned int start,
03349      unsigned int length)
03350 {
03351     size_t slen = p_term_name_length_utf8(str);
03352     const char *sstart;
03353     const char *sposn;
03354     size_t ch_size;
03355     if (!slen)
03356         return str;
03357     if (start >= slen)
03358         return p_term_create_string_n(context, "", 0);
03359     if (start == 0 && length >= slen)
03360         return str;
03361     if (length > (slen - start))
03362         length = (unsigned int)(slen - start);
03363     sstart = p_term_name(str);
03364     while (slen > 0 && start > 0) {
03365         _p_term_next_utf8(sstart, slen, &ch_size);
03366         sstart += ch_size;
03367         --slen;
03368         --start;
03369     }
03370     sposn = sstart;
03371     while (slen > 0 && length > 0) {
03372         _p_term_next_utf8(sposn, slen, &ch_size);
03373         sposn += ch_size;
03374         --slen;
03375         --length;
03376     }
03377     return p_term_create_string_n(context, sstart, sposn - sstart);
03378 }
03379 static p_goal_result p_arith_left
03380     (p_context *context, p_arith_value *result,
03381      const p_arith_value *values, p_term **args, p_term **error)
03382 {
03383     p_term *str;
03384     int length;
03385     if (values[0].type != P_TERM_STRING) {
03386         *error = p_create_type_error(context, "string", args[0]);
03387         return P_RESULT_ERROR;
03388     }
03389     if (values[1].type != P_TERM_INTEGER) {
03390         *error = p_create_type_error(context, "integer", args[1]);
03391         return P_RESULT_ERROR;
03392     }
03393     str = values[0].string_value;
03394     length = values[1].integer_value;
03395     if (length < 0) {
03396         *error = p_create_domain_error
03397             (context, "not_less_than_zero", args[1]);
03398         return P_RESULT_ERROR;
03399     }
03400     result->type = P_TERM_STRING;
03401     result->string_value = p_arith_mid
03402         (context, str, 0, (unsigned int)length);
03403     return P_RESULT_TRUE;
03404 }
03405 
03447 static p_term *p_arith_mid_bytes
03448     (p_context *context, p_term *str, unsigned int start,
03449      unsigned int length)
03450 {
03451     if (!str->header.size)
03452         return str;
03453     if (start >= str->header.size)
03454         return p_term_create_string_n(context, "", 0);
03455     if (start == 0 && length >= str->header.size)
03456         return str;
03457     if (length > (str->header.size - start))
03458         length = str->header.size - start;
03459     return p_term_create_string_n
03460         (context, str->string.name + start, length);
03461 }
03462 static p_goal_result p_arith_left_bytes
03463     (p_context *context, p_arith_value *result,
03464      const p_arith_value *values, p_term **args, p_term **error)
03465 {
03466     p_term *str;
03467     int length;
03468     if (values[0].type != P_TERM_STRING) {
03469         *error = p_create_type_error(context, "string", args[0]);
03470         return P_RESULT_ERROR;
03471     }
03472     if (values[1].type != P_TERM_INTEGER) {
03473         *error = p_create_type_error(context, "integer", args[1]);
03474         return P_RESULT_ERROR;
03475     }
03476     str = values[0].string_value;
03477     length = values[1].integer_value;
03478     if (length < 0) {
03479         *error = p_create_domain_error
03480             (context, "not_less_than_zero", args[1]);
03481         return P_RESULT_ERROR;
03482     }
03483     result->type = P_TERM_STRING;
03484     result->string_value = p_arith_mid_bytes
03485         (context, str, 0, (unsigned int)length);
03486     return P_RESULT_TRUE;
03487 }
03488 
03521 static p_goal_result p_arith_length
03522     (p_context *context, p_arith_value *result,
03523      const p_arith_value *values, p_term **args, p_term **error)
03524 {
03525     if (values[0].type == P_TERM_STRING) {
03526         result->type = P_TERM_INTEGER;
03527         result->integer_value = (int)
03528             p_term_name_length_utf8(values[0].string_value);
03529         return P_RESULT_TRUE;
03530     } else {
03531         *error = p_create_type_error(context, "string", args[0]);
03532         return P_RESULT_ERROR;
03533     }
03534 }
03535 
03567 static p_goal_result p_arith_length_bytes
03568     (p_context *context, p_arith_value *result,
03569      const p_arith_value *values, p_term **args, p_term **error)
03570 {
03571     if (values[0].type == P_TERM_STRING) {
03572         result->type = P_TERM_INTEGER;
03573         result->integer_value = (int)
03574             p_term_name_length(values[0].string_value);
03575         return P_RESULT_TRUE;
03576     } else {
03577         *error = p_create_type_error(context, "string", args[0]);
03578         return P_RESULT_ERROR;
03579     }
03580 }
03581 
03622 static p_goal_result p_arith_log
03623     (p_context *context, p_arith_value *result,
03624      const p_arith_value *values, p_term **args, p_term **error)
03625 {
03626     if (values[0].type == P_TERM_INTEGER) {
03627         result->type = P_TERM_REAL;
03628         result->real_value = log((double)(values[0].integer_value));
03629         return P_RESULT_TRUE;
03630     } else if (values[0].type == P_TERM_REAL) {
03631         result->type = P_TERM_REAL;
03632         result->real_value = log(values[0].real_value);
03633         return P_RESULT_TRUE;
03634     } else {
03635         *error = p_create_type_error(context, "number", args[0]);
03636         return P_RESULT_ERROR;
03637     }
03638 }
03639 
03698 static p_goal_result p_arith_mid_2
03699     (p_context *context, p_arith_value *result,
03700      const p_arith_value *values, p_term **args, p_term **error)
03701 {
03702     p_term *str;
03703     int start;
03704     if (values[0].type != P_TERM_STRING) {
03705         *error = p_create_type_error(context, "string", args[0]);
03706         return P_RESULT_ERROR;
03707     }
03708     if (values[1].type != P_TERM_INTEGER) {
03709         *error = p_create_type_error(context, "integer", args[1]);
03710         return P_RESULT_ERROR;
03711     }
03712     str = values[0].string_value;
03713     start = values[1].integer_value;
03714     if (start < 0) {
03715         *error = p_create_domain_error
03716             (context, "not_less_than_zero", args[1]);
03717         return P_RESULT_ERROR;
03718     }
03719     result->type = P_TERM_STRING;
03720     result->string_value = p_arith_mid
03721         (context, str, (unsigned int)start, str->header.size);
03722     return P_RESULT_TRUE;
03723 }
03724 static p_goal_result p_arith_mid_3
03725     (p_context *context, p_arith_value *result,
03726      const p_arith_value *values, p_term **args, p_term **error)
03727 {
03728     p_term *str;
03729     int start;
03730     int length;
03731     if (values[0].type != P_TERM_STRING) {
03732         *error = p_create_type_error(context, "string", args[0]);
03733         return P_RESULT_ERROR;
03734     }
03735     if (values[1].type != P_TERM_INTEGER) {
03736         *error = p_create_type_error(context, "integer", args[1]);
03737         return P_RESULT_ERROR;
03738     }
03739     if (values[2].type != P_TERM_INTEGER) {
03740         *error = p_create_type_error(context, "integer", args[2]);
03741         return P_RESULT_ERROR;
03742     }
03743     str = values[0].string_value;
03744     start = values[1].integer_value;
03745     length = values[2].integer_value;
03746     if (start < 0) {
03747         *error = p_create_domain_error
03748             (context, "not_less_than_zero", args[1]);
03749         return P_RESULT_ERROR;
03750     }
03751     if (length < 0) {
03752         *error = p_create_domain_error
03753             (context, "not_less_than_zero", args[2]);
03754         return P_RESULT_ERROR;
03755     }
03756     result->type = P_TERM_STRING;
03757     result->string_value = p_arith_mid
03758         (context, str, (unsigned int)start, (unsigned int)length);
03759     return P_RESULT_TRUE;
03760 }
03761 
03823 static p_goal_result p_arith_mid_bytes_2
03824     (p_context *context, p_arith_value *result,
03825      const p_arith_value *values, p_term **args, p_term **error)
03826 {
03827     p_term *str;
03828     int start;
03829     if (values[0].type != P_TERM_STRING) {
03830         *error = p_create_type_error(context, "string", args[0]);
03831         return P_RESULT_ERROR;
03832     }
03833     if (values[1].type != P_TERM_INTEGER) {
03834         *error = p_create_type_error(context, "integer", args[1]);
03835         return P_RESULT_ERROR;
03836     }
03837     str = values[0].string_value;
03838     start = values[1].integer_value;
03839     if (start < 0) {
03840         *error = p_create_domain_error
03841             (context, "not_less_than_zero", args[1]);
03842         return P_RESULT_ERROR;
03843     }
03844     result->type = P_TERM_STRING;
03845     result->string_value = p_arith_mid_bytes
03846         (context, str, (unsigned int)start, str->header.size);
03847     return P_RESULT_TRUE;
03848 }
03849 static p_goal_result p_arith_mid_bytes_3
03850     (p_context *context, p_arith_value *result,
03851      const p_arith_value *values, p_term **args, p_term **error)
03852 {
03853     p_term *str;
03854     int start;
03855     int length;
03856     if (values[0].type != P_TERM_STRING) {
03857         *error = p_create_type_error(context, "string", args[0]);
03858         return P_RESULT_ERROR;
03859     }
03860     if (values[1].type != P_TERM_INTEGER) {
03861         *error = p_create_type_error(context, "integer", args[1]);
03862         return P_RESULT_ERROR;
03863     }
03864     if (values[2].type != P_TERM_INTEGER) {
03865         *error = p_create_type_error(context, "integer", args[2]);
03866         return P_RESULT_ERROR;
03867     }
03868     str = values[0].string_value;
03869     start = values[1].integer_value;
03870     length = values[2].integer_value;
03871     if (start < 0) {
03872         *error = p_create_domain_error
03873             (context, "not_less_than_zero", args[1]);
03874         return P_RESULT_ERROR;
03875     }
03876     if (length < 0) {
03877         *error = p_create_domain_error
03878             (context, "not_less_than_zero", args[2]);
03879         return P_RESULT_ERROR;
03880     }
03881     result->type = P_TERM_STRING;
03882     result->string_value = p_arith_mid_bytes
03883         (context, str, (unsigned int)start, (unsigned int)length);
03884     return P_RESULT_TRUE;
03885 }
03886 
03912 static p_goal_result p_arith_nan
03913     (p_context *context, p_arith_value *result,
03914      const p_arith_value *values, p_term **args, p_term **error)
03915 {
03916     result->type = P_TERM_REAL;
03917     result->real_value = 0.0 / 0.0;
03918     return P_RESULT_TRUE;
03919 }
03920 
03944 static p_goal_result p_arith_pi
03945     (p_context *context, p_arith_value *result,
03946      const p_arith_value *values, p_term **args, p_term **error)
03947 {
03948     result->type = P_TERM_REAL;
03949     result->real_value = 3.14159265358979323846;
03950     return P_RESULT_TRUE;
03951 }
03952 
04011 static p_goal_result p_arith_pow
04012     (p_context *context, p_arith_value *result,
04013      const p_arith_value *values, p_term **args, p_term **error)
04014 {
04015     if (values[0].type == P_TERM_INTEGER) {
04016         if (values[1].type == P_TERM_INTEGER) {
04017             result->type = P_TERM_REAL;
04018             result->real_value =
04019                 pow(values[0].integer_value, values[1].integer_value);
04020             return P_RESULT_TRUE;
04021         } else if (values[1].type == P_TERM_REAL) {
04022             result->type = P_TERM_REAL;
04023             result->real_value =
04024                 pow(values[0].integer_value, values[1].real_value);
04025             return P_RESULT_TRUE;
04026         } else {
04027             *error = p_create_type_error(context, "number", args[1]);
04028             return P_RESULT_ERROR;
04029         }
04030     } else if (values[0].type == P_TERM_REAL) {
04031         if (values[1].type == P_TERM_REAL) {
04032             result->type = P_TERM_REAL;
04033             result->real_value =
04034                 pow(values[0].real_value, values[1].real_value);
04035             return P_RESULT_TRUE;
04036         } else if (values[1].type == P_TERM_INTEGER) {
04037             result->type = P_TERM_REAL;
04038             result->real_value =
04039                 pow(values[0].real_value, values[1].integer_value);
04040             return P_RESULT_TRUE;
04041         } else {
04042             *error = p_create_type_error(context, "number", args[1]);
04043             return P_RESULT_ERROR;
04044         }
04045     } else {
04046         *error = p_create_type_error(context, "number", args[0]);
04047         return P_RESULT_ERROR;
04048     }
04049 }
04050 
04076 static p_goal_result p_arith_random
04077     (p_context *context, p_arith_value *result,
04078      const p_arith_value *values, p_term **args, p_term **error)
04079 {
04080     context->random_seed = context->random_seed * 1103515245 + 12345;
04081     result->type = P_TERM_REAL;
04082     result->real_value =
04083         (((int)(context->random_seed)) & 0x7FFFFFFF) / 2147483648.0;
04084     return P_RESULT_TRUE;
04085 }
04086 
04128 static p_goal_result p_arith_right
04129     (p_context *context, p_arith_value *result,
04130      const p_arith_value *values, p_term **args, p_term **error)
04131 {
04132     p_term *str;
04133     int length;
04134     size_t str_len;
04135     if (values[0].type != P_TERM_STRING) {
04136         *error = p_create_type_error(context, "string", args[0]);
04137         return P_RESULT_ERROR;
04138     }
04139     if (values[1].type != P_TERM_INTEGER) {
04140         *error = p_create_type_error(context, "integer", args[1]);
04141         return P_RESULT_ERROR;
04142     }
04143     str = values[0].string_value;
04144     length = values[1].integer_value;
04145     if (length < 0) {
04146         *error = p_create_domain_error
04147             (context, "not_less_than_zero", args[1]);
04148         return P_RESULT_ERROR;
04149     }
04150     result->type = P_TERM_STRING;
04151     str_len = p_term_name_length_utf8(str);
04152     if (((size_t)length) >= str_len) {
04153         result->string_value = str;
04154     } else {
04155         result->string_value = p_arith_mid
04156             (context, str, (unsigned int)(str_len - (size_t)length),
04157              (unsigned int)length);
04158     }
04159     return P_RESULT_TRUE;
04160 }
04161 
04203 static p_goal_result p_arith_right_bytes
04204     (p_context *context, p_arith_value *result,
04205      const p_arith_value *values, p_term **args, p_term **error)
04206 {
04207     p_term *str;
04208     int length;
04209     if (values[0].type != P_TERM_STRING) {
04210         *error = p_create_type_error(context, "string", args[0]);
04211         return P_RESULT_ERROR;
04212     }
04213     if (values[1].type != P_TERM_INTEGER) {
04214         *error = p_create_type_error(context, "integer", args[1]);
04215         return P_RESULT_ERROR;
04216     }
04217     str = values[0].string_value;
04218     length = values[1].integer_value;
04219     if (length < 0) {
04220         *error = p_create_domain_error
04221             (context, "not_less_than_zero", args[1]);
04222         return P_RESULT_ERROR;
04223     }
04224     result->type = P_TERM_STRING;
04225     if (length >= str->header.size) {
04226         result->string_value = str;
04227     } else {
04228         result->string_value = p_arith_mid_bytes
04229             (context, str, str->header.size - (unsigned int)length,
04230              (unsigned int)length);
04231     }
04232     return P_RESULT_TRUE;
04233 }
04234 
04235 
04236 
04237 P_INLINE double p_arith_round_nearest(double x)
04238 {
04239     if (x >= 0.0) {
04240         double y = floor(x);
04241         if ((x - y) >= 0.5)
04242             return ceil(x);
04243         else
04244             return y;
04245     } else {
04246         double y = ceil(x);
04247         if ((x - y) <= -0.5)
04248             return floor(x);
04249         else
04250             return y;
04251     }
04252 }
04253 
04299 static p_goal_result p_arith_round
04300     (p_context *context, p_arith_value *result,
04301      const p_arith_value *values, p_term **args, p_term **error)
04302 {
04303     if (values[0].type == P_TERM_INTEGER) {
04304         result->type = P_TERM_INTEGER;
04305         result->integer_value = values[0].integer_value;
04306         return P_RESULT_TRUE;
04307     } else if (values[0].type == P_TERM_REAL) {
04308         result->type = P_TERM_REAL;
04309         result->real_value =
04310             p_arith_round_nearest(values[0].real_value);
04311         return P_RESULT_TRUE;
04312     } else {
04313         *error = p_create_type_error(context, "number", args[0]);
04314         return P_RESULT_ERROR;
04315     }
04316 }
04317 
04355 static p_goal_result p_arith_sign
04356     (p_context *context, p_arith_value *result,
04357      const p_arith_value *values, p_term **args, p_term **error)
04358 {
04359     if (values[0].type == P_TERM_INTEGER) {
04360         result->type = P_TERM_INTEGER;
04361         if (values[0].integer_value < 0)
04362             result->integer_value = -1;
04363         else if (values[0].integer_value > 0)
04364             result->integer_value = 1;
04365         else
04366             result->integer_value = 0;
04367         return P_RESULT_TRUE;
04368     } else if (values[0].type == P_TERM_REAL) {
04369         result->type = P_TERM_INTEGER;
04370         if (values[0].real_value < 0.0)
04371             result->integer_value = -1;
04372         else if (values[0].real_value > 0.0)
04373             result->integer_value = 1;
04374         else
04375             result->integer_value = 0;
04376         return P_RESULT_TRUE;
04377     } else {
04378         *error = p_create_type_error(context, "number", args[0]);
04379         return P_RESULT_ERROR;
04380     }
04381 }
04382 
04422 static p_goal_result p_arith_sin
04423     (p_context *context, p_arith_value *result,
04424      const p_arith_value *values, p_term **args, p_term **error)
04425 {
04426     if (values[0].type == P_TERM_INTEGER) {
04427         result->type = P_TERM_REAL;
04428         result->real_value = sin((double)(values[0].integer_value));
04429         return P_RESULT_TRUE;
04430     } else if (values[0].type == P_TERM_REAL) {
04431         result->type = P_TERM_REAL;
04432         result->real_value = sin(values[0].real_value);
04433         return P_RESULT_TRUE;
04434     } else {
04435         *error = p_create_type_error(context, "number", args[0]);
04436         return P_RESULT_ERROR;
04437     }
04438 }
04439 
04478 static p_goal_result p_arith_sqrt
04479     (p_context *context, p_arith_value *result,
04480      const p_arith_value *values, p_term **args, p_term **error)
04481 {
04482     if (values[0].type == P_TERM_INTEGER) {
04483         result->type = P_TERM_REAL;
04484         result->real_value = sqrt((double)(values[0].integer_value));
04485         return P_RESULT_TRUE;
04486     } else if (values[0].type == P_TERM_REAL) {
04487         result->type = P_TERM_REAL;
04488         result->real_value = sqrt(values[0].real_value);
04489         return P_RESULT_TRUE;
04490     } else {
04491         *error = p_create_type_error(context, "number", args[0]);
04492         return P_RESULT_ERROR;
04493     }
04494 }
04495 
04532 static p_goal_result p_arith_string
04533     (p_context *context, p_arith_value *result,
04534      const p_arith_value *values, p_term **args, p_term **error)
04535 {
04536     char buffer[128];
04537     if (values[0].type == P_TERM_INTEGER) {
04538         result->type = P_TERM_STRING;
04539         snprintf(buffer, sizeof(buffer), "%d", values[0].integer_value);
04540         result->string_value = p_term_create_string(context, buffer);
04541         return P_RESULT_TRUE;
04542     } else if (values[0].type == P_TERM_REAL) {
04543         result->type = P_TERM_STRING;
04544         if (isnan(values[0].real_value)) {
04545             result->string_value = p_term_create_string(context, "nan");
04546             return P_RESULT_TRUE;
04547         } else if (isinf(values[0].real_value) != 0) {
04548             if (values[0].real_value < 0)
04549                 result->string_value = p_term_create_string(context, "-inf");
04550             else
04551                 result->string_value = p_term_create_string(context, "inf");
04552             return P_RESULT_TRUE;
04553         }
04554         snprintf(buffer, sizeof(buffer) - 8,
04555                  "%.10g", values[0].real_value);
04556         if (strchr(buffer, '.') == 0 && strchr(buffer, 'e') == 0) {
04557             
04558             strcat(buffer, ".0");
04559         }
04560         result->string_value = p_term_create_string(context, buffer);
04561         return P_RESULT_TRUE;
04562     } else if (values[0].type == P_TERM_STRING) {
04563         result->type = P_TERM_STRING;
04564         result->string_value = values[0].string_value;
04565         return P_RESULT_TRUE;
04566     } else {
04567         *error = p_create_type_error(context, "string", args[0]);
04568         return P_RESULT_ERROR;
04569     }
04570 }
04571 
04608 static p_goal_result p_arith_string_2
04609     (p_context *context, p_arith_value *result,
04610      const p_arith_value *values, p_term **args, p_term **error)
04611 {
04612     char prec[64];
04613     char buffer[128];
04614     if (values[1].type != P_TERM_INTEGER) {
04615         *error = p_create_type_error(context, "integer", args[1]);
04616         return P_RESULT_ERROR;
04617     }
04618     if (values[0].type == P_TERM_INTEGER) {
04619         result->type = P_TERM_STRING;
04620         snprintf(buffer, sizeof(buffer), "%d", values[0].integer_value);
04621         result->string_value = p_term_create_string(context, buffer);
04622         return P_RESULT_TRUE;
04623     } else if (values[0].type == P_TERM_REAL) {
04624         result->type = P_TERM_STRING;
04625         if (isnan(values[0].real_value)) {
04626             result->string_value = p_term_create_string(context, "nan");
04627             return P_RESULT_TRUE;
04628         } else if (isinf(values[0].real_value) != 0) {
04629             if (values[0].real_value < 0)
04630                 result->string_value = p_term_create_string(context, "-inf");
04631             else
04632                 result->string_value = p_term_create_string(context, "inf");
04633             return P_RESULT_TRUE;
04634         }
04635         snprintf(prec, sizeof(prec), "%%.%dg", values[1].integer_value);
04636         snprintf(buffer, sizeof(buffer) - 8,
04637                  prec, values[0].real_value);
04638         if (strchr(buffer, '.') == 0 && strchr(buffer, 'e') == 0) {
04639             
04640             strcat(buffer, ".0");
04641         }
04642         result->string_value = p_term_create_string(context, buffer);
04643         return P_RESULT_TRUE;
04644     } else if (values[0].type == P_TERM_STRING) {
04645         result->type = P_TERM_STRING;
04646         result->string_value = values[0].string_value;
04647         return P_RESULT_TRUE;
04648     } else {
04649         *error = p_create_type_error(context, "string", args[0]);
04650         return P_RESULT_ERROR;
04651     }
04652 }
04653 
04690 static p_goal_result p_arith_tan
04691     (p_context *context, p_arith_value *result,
04692      const p_arith_value *values, p_term **args, p_term **error)
04693 {
04694     if (values[0].type == P_TERM_INTEGER) {
04695         result->type = P_TERM_REAL;
04696         result->real_value = tan((double)(values[0].integer_value));
04697         return P_RESULT_TRUE;
04698     } else if (values[0].type == P_TERM_REAL) {
04699         result->type = P_TERM_REAL;
04700         result->real_value = tan(values[0].real_value);
04701         return P_RESULT_TRUE;
04702     } else {
04703         *error = p_create_type_error(context, "number", args[0]);
04704         return P_RESULT_ERROR;
04705     }
04706 }
04707 
04708 void _p_db_init_arith(p_context *context)
04709 {
04710     static struct p_builtin const builtins[] = {
04711         
04712         {"is", 2, p_builtin_is},
04713         {"=:=", 2, p_builtin_num_eq},
04714         {"=!=", 2, p_builtin_num_ne},
04715         {"=\\=", 2, p_builtin_num_ne},
04716         {"<", 2, p_builtin_num_lt},
04717         {"<=", 2, p_builtin_num_le},
04718         {"=<", 2, p_builtin_num_le},
04719         {">", 2, p_builtin_num_gt},
04720         {">=", 2, p_builtin_num_ge},
04721         {"atom_name", 2, p_builtin_atom_name},
04722         {"fperror", 1, p_builtin_fperror},
04723         {"isnan", 1, p_builtin_isnan},
04724         {"isinf", 1, p_builtin_isinf},
04725         {"randomize", 0, p_builtin_randomize_0},
04726         {"randomize", 1, p_builtin_randomize_1},
04727         {0, 0, 0}
04728     };
04729     static struct p_arith const ariths[] = {
04730         
04731         {"+", 2, p_arith_add},
04732         {"-", 1, p_arith_neg},
04733         {"-", 2, p_arith_sub},
04734         {"*", 2, p_arith_mul},
04735         {"/", 2, p_arith_div},
04736         {"%", 2, p_arith_mod},
04737         {"**", 2, p_arith_pow},
04738         {"/\\", 2, p_arith_and},
04739         {"\\/", 2, p_arith_or},
04740         {"^", 2, p_arith_xor},
04741         {"~", 1, p_arith_not},
04742         {"\\", 1, p_arith_not},
04743         {"<<", 2, p_arith_lshift},
04744         {">>", 2, p_arith_rshift},
04745         {">>>", 2, p_arith_rushift},
04746         {"abs", 1, p_arith_abs},
04747         {"acos", 1, p_arith_acos},
04748         {"asin", 1, p_arith_asin},
04749         {"atan", 1, p_arith_atan},
04750         {"atan2", 2, p_arith_atan2},
04751         {"byte", 2, p_arith_byte},
04752         {"byte_to_string", 1, p_arith_byte_to_string},
04753         {"ceil", 1, p_arith_ceil},
04754         {"ceiling", 1, p_arith_ceil},
04755         {"char", 2, p_arith_char},
04756         {"char_to_string", 1, p_arith_char_to_string},
04757         {"cos", 1, p_arith_cos},
04758         {"e", 0, p_arith_e},
04759         {"exp", 1, p_arith_exp},
04760         {"float", 1, p_arith_float},
04761         {"float_fractional_part", 1, p_arith_float_fractional_part},
04762         {"float_integer_part", 1, p_arith_float_integer_part},
04763         {"floor", 1, p_arith_floor},
04764         {"inf", 0, p_arith_inf},
04765         {"integer", 1, p_arith_integer},
04766         {"left", 2, p_arith_left},
04767         {"left_bytes", 2, p_arith_left_bytes},
04768         {"length", 1, p_arith_length},
04769         {"length_bytes", 1, p_arith_length_bytes},
04770         {"log", 1, p_arith_log},
04771         {"mid", 2, p_arith_mid_2},
04772         {"mid", 3, p_arith_mid_3},
04773         {"mid_bytes", 2, p_arith_mid_bytes_2},
04774         {"mid_bytes", 3, p_arith_mid_bytes_3},
04775         {"mod", 2, p_arith_mod},
04776         {"nan", 0, p_arith_nan},
04777         {"pi", 0, p_arith_pi},
04778         {"pow", 2, p_arith_pow},
04779         {"random", 0, p_arith_random},
04780         {"rem", 2, p_arith_rem},
04781         {"right", 2, p_arith_right},
04782         {"right_bytes", 2, p_arith_right_bytes},
04783         {"round", 1, p_arith_round},
04784         {"sign", 1, p_arith_sign},
04785         {"sin", 1, p_arith_sin},
04786         {"sqrt", 1, p_arith_sqrt},
04787         {"string", 1, p_arith_string},
04788         {"string", 2, p_arith_string_2},
04789         {"tan", 1, p_arith_tan},
04790         {"truncate", 1, p_arith_integer},
04791         {0, 0, 0}
04792     };
04793     _p_db_register_builtins(context, builtins);
04794     _p_db_register_ariths(context, ariths);
04795 }