annotate plutils.c @ 3:974d7be8eec4 tip

Update to pack-based dcg utilities
author samer
date Tue, 03 Oct 2017 11:52:23 +0100
parents b31415b4a196
children
rev   line source
samer@0 1 /*
samer@0 2 * Prolog-C utilities
samer@0 3 * Samer Abdallah (2009)
samer@0 4 */
samer@0 5
samer@0 6 //#define _USE_MATH_DEFINES 1
samer@0 7 //#include "plutils.h"
samer@0 8
samer@0 9 //#include <math.h>
samer@0 10 //#include <float.h>
samer@0 11
samer@0 12 // throws a Prolog exception to signal type error
samer@0 13 int type_error(term_t actual, const char *expected)
samer@0 14 {
samer@0 15 term_t ex = PL_new_term_ref();
samer@0 16 int rc = PL_unify_term(ex, PL_FUNCTOR_CHARS, "error", 2,
samer@0 17 PL_FUNCTOR_CHARS, "type_error", 2,
samer@0 18 PL_CHARS, expected,
samer@0 19 PL_TERM, actual,
samer@0 20 PL_VARIABLE);
samer@0 21
samer@0 22 return rc && PL_raise_exception(ex);
samer@0 23 }
samer@0 24
samer@0 25 double sum_array(double *p, int n) {
samer@0 26 double tot=0;
samer@0 27 int i;
samer@0 28 for (i=0; i<n; i++) tot+=*p++;
samer@0 29 return tot;
samer@0 30 }
samer@0 31
samer@0 32 int memory_error(size_t amount)
samer@0 33 {
samer@0 34 term_t ex = PL_new_term_ref();
samer@0 35 int rc = PL_unify_term(ex, PL_FUNCTOR_CHARS, "error", 2,
samer@0 36 PL_FUNCTOR_CHARS, "memory_error", 1,
samer@0 37 PL_INTEGER, amount,
samer@0 38 PL_VARIABLE);
samer@0 39
samer@0 40 return rc && PL_raise_exception(ex);
samer@0 41 }
samer@0 42
samer@0 43 // extract double from Prolog float
samer@0 44 int get_double(term_t term, double *p)
samer@0 45 {
samer@0 46 if (PL_get_float(term, p)) return TRUE;
samer@0 47 else return type_error(term, "float");
samer@0 48 }
samer@0 49
samer@0 50 // extract long from Prolog integer
samer@0 51 int get_long(term_t term, long *p)
samer@0 52 {
samer@0 53 if (PL_get_long(term, p)) return TRUE;
samer@0 54 else return type_error(term, "integer");
samer@0 55 }
samer@0 56
samer@0 57
samer@0 58 // unify Prolog list of floats with array of doubles
samer@0 59 int unify_list_doubles(term_t list, double *x, int n)
samer@0 60 {
samer@0 61 int i;
samer@0 62 list=PL_copy_term_ref(list);
samer@0 63
samer@0 64 for (i=0; i<n; i++) {
samer@0 65 term_t head=PL_new_term_ref();
samer@0 66 term_t tail=PL_new_term_ref();
samer@0 67 if (!PL_unify_list(list,head,tail)) PL_fail;
samer@0 68 if (!PL_unify_float(head,x[i])) PL_fail;
samer@0 69 list=tail;
samer@0 70 }
samer@0 71 return PL_unify_nil(list);
samer@0 72 }
samer@0 73
samer@0 74 // read list of floats from term and write to double array
samer@0 75 int get_list_doubles(term_t list, double *vals, int len)
samer@0 76 {
samer@0 77 term_t head=PL_new_term_ref();
samer@0 78 int n;
samer@0 79
samer@0 80 // copy term ref so as not to modify original
samer@0 81 list=PL_copy_term_ref(list);
samer@0 82 for (n=0; n<len && PL_get_list(list,head,list);n++) {
samer@0 83 if (!PL_get_float(head,&vals[n])) return FALSE;
samer@0 84 }
samer@0 85 if (!PL_get_nil(list)) return FALSE;
samer@0 86 return TRUE;
samer@0 87 }
samer@0 88
samer@0 89 int unify_args_doubles(term_t state, double *p, int n)
samer@0 90 {
samer@0 91 term_t arg = PL_new_term_ref();
samer@0 92 int i;
samer@0 93
samer@0 94 for (i=0; i<n; i++) {
samer@0 95 if (!PL_put_float(arg,p[i])) PL_fail;
samer@0 96 if (!PL_unify_arg(i+1,state,arg)) PL_fail;
samer@0 97 }
samer@0 98 return TRUE;
samer@0 99 }
samer@0 100
samer@0 101 int get_args_doubles(term_t state, double *p, int n)
samer@0 102 {
samer@0 103 term_t arg = PL_new_term_ref();
samer@0 104 int i;
samer@0 105
samer@0 106 for (i=0; i<n; i++) {
samer@0 107 _PL_get_arg(i+1, state, arg);
samer@0 108 if (!get_double(arg, p+i)) return FALSE;
samer@0 109 }
samer@0 110 return TRUE;
samer@0 111 }
samer@0 112
samer@0 113 int alloc_array(size_t N, size_t SZ, void **PP) {
samer@0 114 *PP=calloc(N,SZ);
samer@0 115 if (*PP) return TRUE;
samer@0 116 else return memory_error(N*SZ);
samer@0 117 }
samer@0 118