1/*
2 * Copyright 2010      INRIA Saclay
3 * Copyright 2013      Ecole Normale Superieure
4 *
5 * Use of this software is governed by the MIT license
6 *
7 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
8 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
9 * 91893 Orsay, France
10 * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
11 */
12
13#include <isl/val.h>
14#include <isl_space_private.h>
15#include <isl_point_private.h>
16
17#include <isl_pw_macro.h>
18
19#undef SUFFIX
20#define SUFFIX	point
21#undef ARG1
22#define ARG1	PW
23#undef ARG2
24#define ARG2	isl_point
25
26static
27#include "isl_align_params_templ.c"
28
29/* Evaluate "pw" in the void point "pnt".
30 * In particular, return the value NaN.
31 */
32static __isl_give isl_val *FN(PW,eval_void)(__isl_take PW *pw,
33	__isl_take isl_point *pnt)
34{
35	isl_ctx *ctx;
36
37	ctx = isl_point_get_ctx(pnt);
38	FN(PW,free)(pw);
39	isl_point_free(pnt);
40	return isl_val_nan(ctx);
41}
42
43/* Evaluate the piecewise function "pw" in "pnt".
44 * If the point is void, then return NaN.
45 * If the point lies outside the domain of "pw", then return 0 or NaN
46 * depending on whether 0 is the default value for this type of function.
47 *
48 * Align the parameters if needed, but "pnt" should specify a value
49 * for all parameters in "pw".
50 */
51__isl_give isl_val *FN(PW,eval)(__isl_take PW *pw, __isl_take isl_point *pnt)
52{
53	int i;
54	isl_bool is_void;
55	isl_bool found;
56	isl_ctx *ctx;
57	isl_bool ok;
58	isl_space *pnt_space, *pw_space;
59	isl_val *v;
60
61	FN(PW,align_params_point)(&pw, &pnt);
62
63	pnt_space = isl_point_peek_space(pnt);
64	pw_space = FN(PW,peek_space)(pw);
65	ok = isl_space_is_domain_internal(pnt_space, pw_space);
66	if (ok < 0)
67		goto error;
68	ctx = isl_point_get_ctx(pnt);
69	if (!ok)
70		isl_die(ctx, isl_error_invalid,
71			"incompatible spaces", goto error);
72	is_void = isl_point_is_void(pnt);
73	if (is_void < 0)
74		goto error;
75	if (is_void)
76		return FN(PW,eval_void)(pw, pnt);
77
78	found = isl_bool_false;
79	for (i = 0; i < pw->n; ++i) {
80		found = isl_set_contains_point(pw->p[i].set, pnt);
81		if (found < 0)
82			goto error;
83		if (found)
84			break;
85	}
86	if (found) {
87		v = FN(EL,eval)(FN(EL,copy)(pw->p[i].FIELD),
88					    isl_point_copy(pnt));
89	} else if (DEFAULT_IS_ZERO) {
90		v = isl_val_zero(ctx);
91	} else {
92		v = isl_val_nan(ctx);
93	}
94	FN(PW,free)(pw);
95	isl_point_free(pnt);
96	return v;
97error:
98	FN(PW,free)(pw);
99	isl_point_free(pnt);
100	return NULL;
101}
102