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 "context-priv.h"
00023 #include "database-priv.h"
00024 
00025 p_goal_result p_arith_eval
00026     (p_context *context, p_arith_value *result,
00027      p_term *expr, p_term **error);
00028 
00029 static p_goal_result p_builtin_fuzzy_1
00030     (p_context *context, p_term **args, p_term **error)
00031 {
00032     p_arith_value value;
00033     p_goal_result result;
00034     double fuzzy;
00035     p_term *expr = p_term_deref_member(context, args[0]);
00036     if (p_term_type(expr) & P_TERM_VARIABLE) {
00037         if (p_term_unify(context, expr,
00038                          p_term_create_real
00039                             (context, context->confidence),
00040                          P_BIND_DEFAULT))
00041             return P_RESULT_TRUE;
00042         else
00043             return P_RESULT_FAIL;
00044     } else {
00045         result = p_arith_eval(context, &value, expr, error);
00046         if (result != P_RESULT_TRUE)
00047             return result;
00048         if (value.type == P_TERM_INTEGER) {
00049             fuzzy = (double)(value.integer_value);
00050         } else if (value.type == P_TERM_REAL) {
00051             fuzzy = value.real_value;
00052         } else {
00053             *error = p_create_type_error(context, "number", expr);
00054             return P_RESULT_ERROR;
00055         }
00056         if (fuzzy <= 0.0)
00057             return P_RESULT_FAIL;
00058         if (fuzzy < context->confidence)
00059             context->confidence = fuzzy;
00060         return P_RESULT_TRUE;
00061     }
00062 }
00063 
00064 static p_goal_result p_builtin_set_fuzzy
00065     (p_context *context, p_term **args, p_term **error)
00066 {
00067     p_arith_value value;
00068     p_goal_result result;
00069     double fuzzy;
00070     result = p_arith_eval(context, &value, args[0], error);
00071     if (result != P_RESULT_TRUE)
00072         return result;
00073     if (value.type == P_TERM_INTEGER) {
00074         fuzzy = (double)(value.integer_value);
00075     } else if (value.type == P_TERM_REAL) {
00076         fuzzy = value.real_value;
00077     } else {
00078         *error = p_create_type_error(context, "number", args[0]);
00079         return P_RESULT_ERROR;
00080     }
00081     if (fuzzy <= 0.0)
00082         return P_RESULT_FAIL;
00083     if (fuzzy > 1.0)
00084         fuzzy = 1.0;
00085     context->confidence = fuzzy;
00086     return P_RESULT_TRUE;
00087 }
00088 
00089 static p_goal_result p_builtin_register_fuzzy
00090     (p_context *context, p_term **args, p_term **error)
00091 {
00092     static struct p_builtin const builtins[] = {
00093         {"fuzzy", 1, p_builtin_fuzzy_1},
00094         {"set_fuzzy", 1, p_builtin_set_fuzzy},
00095         {0, 0, 0}
00096     };
00097     _p_db_register_builtins(context, builtins);
00098     return P_RESULT_TRUE;
00099 }
00100 
00101 void _p_db_init_fuzzy(p_context *context)
00102 {
00103     static struct p_builtin const builtins[] = {
00104         {"$$fuzzy", 1, p_builtin_fuzzy_1},
00105         {"$$register_fuzzy_builtins", 0, p_builtin_register_fuzzy},
00106         {"$$set_fuzzy", 1, p_builtin_set_fuzzy},
00107         {0, 0, 0}
00108     };
00109     _p_db_register_builtins(context, builtins);
00110 }