view 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
line wrap: on
line source
/*
 * Prolog-C utilities
 * Samer Abdallah (2009)
 */

//#define _USE_MATH_DEFINES 1
//#include "plutils.h"

//#include <math.h>
//#include <float.h>

// throws a Prolog exception to signal type error
int type_error(term_t actual, const char *expected)
{ 
	term_t ex = PL_new_term_ref();
	int rc = PL_unify_term(ex, PL_FUNCTOR_CHARS, "error", 2,
		      PL_FUNCTOR_CHARS, "type_error", 2,
		        PL_CHARS, expected,
		        PL_TERM, actual,
		      PL_VARIABLE);

  return rc && PL_raise_exception(ex);
}

double sum_array(double *p, int n) {
	double tot=0;
	int	i;
	for (i=0; i<n; i++) tot+=*p++;
	return tot;
}

int memory_error(size_t amount)
{ 
	term_t ex = PL_new_term_ref();
	int rc = PL_unify_term(ex, PL_FUNCTOR_CHARS, "error", 2,
		      PL_FUNCTOR_CHARS, "memory_error", 1,
		        PL_INTEGER, amount,
		      PL_VARIABLE);

	return rc && PL_raise_exception(ex);
}

// extract double from Prolog float
int get_double(term_t term, double *p)
{ 
	if (PL_get_float(term, p)) return TRUE; 
	else return type_error(term, "float");
}

// extract long from Prolog integer
int get_long(term_t term, long *p)
{ 
	if (PL_get_long(term, p)) return TRUE; 
	else return type_error(term, "integer");
}


// unify Prolog list of floats with array of doubles
int unify_list_doubles(term_t list, double *x, int n)
{
	int i;
	list=PL_copy_term_ref(list);

	for (i=0; i<n; i++) {
		term_t head=PL_new_term_ref();
		term_t tail=PL_new_term_ref();
		if (!PL_unify_list(list,head,tail)) PL_fail; 
		if (!PL_unify_float(head,x[i])) PL_fail;
		list=tail;
	}
	return PL_unify_nil(list);
}

// read list of floats from term and write to double array
int get_list_doubles(term_t list, double *vals, int len)
{
	term_t  head=PL_new_term_ref();
	int 		n;

	// copy term ref so as not to modify original
	list=PL_copy_term_ref(list);
	for (n=0; n<len && PL_get_list(list,head,list);n++) {
			if (!PL_get_float(head,&vals[n])) return FALSE;
	}
	if (!PL_get_nil(list)) return FALSE; 
	return TRUE;
}

int unify_args_doubles(term_t state, double *p, int n)
{
	term_t arg = PL_new_term_ref();
	int i;

	for (i=0; i<n; i++) {
		if (!PL_put_float(arg,p[i])) PL_fail;
		if (!PL_unify_arg(i+1,state,arg)) PL_fail;
	}
	return TRUE;
}

int get_args_doubles(term_t state, double *p, int n)
{
	term_t arg = PL_new_term_ref();
	int i;

	for (i=0; i<n; i++) {
		_PL_get_arg(i+1, state, arg);
		if (!get_double(arg, p+i)) return FALSE;
	}
	return TRUE;
}

int alloc_array(size_t N, size_t SZ, void **PP) {
	*PP=calloc(N,SZ);
	if (*PP) return TRUE;
	else return memory_error(N*SZ);
}