1 /* PPL Java interface common routines implementation.
2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4
5 This file is part of the Parma Polyhedra Library (PPL).
6
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23
24 #include "ppl_java_common_defs.hh"
25
26 namespace Parma_Polyhedra_Library {
27
28 namespace Interfaces {
29
30 namespace Java {
31
32 // Define class and field/method ID caches.
33 Java_Class_Cache cached_classes;
34 Java_FMID_Cache cached_FMIDs;
35
Java_Class_Cache()36 Java_Class_Cache::Java_Class_Cache() {
37 // Java Virtual Machine pointer.
38 jvm = NULL;
39 // Non-PPL classes.
40 Boolean = NULL;
41 Integer = NULL;
42 Long = NULL;
43 Iterator = NULL;
44 // PPL classes.
45 Artificial_Parameter = NULL;
46 Artificial_Parameter_Sequence = NULL;
47 Bounded_Integer_Type_Overflow = NULL;
48 Bounded_Integer_Type_Representation = NULL;
49 Bounded_Integer_Type_Width = NULL;
50 By_Reference = NULL;
51 Coefficient = NULL;
52 Congruence = NULL;
53 Constraint = NULL;
54 Generator = NULL;
55 Grid_Generator = NULL;
56 Generator_Type = NULL;
57 Grid_Generator_Type = NULL;
58 Constraint_System = NULL;
59 Congruence_System = NULL;
60 Generator_System = NULL;
61 Grid_Generator_System = NULL;
62 Linear_Expression = NULL;
63 Linear_Expression_Coefficient = NULL;
64 Linear_Expression_Difference = NULL;
65 Linear_Expression_Sum = NULL;
66 Linear_Expression_Times = NULL;
67 Linear_Expression_Unary_Minus = NULL;
68 Linear_Expression_Variable = NULL;
69 MIP_Problem_Status = NULL;
70 Optimization_Mode = NULL;
71 Pair = NULL;
72 PIP_Problem_Control_Parameter_Name = NULL;
73 PIP_Problem_Control_Parameter_Value = NULL;
74 PIP_Problem_Status = NULL;
75 Poly_Con_Relation = NULL;
76 Poly_Gen_Relation = NULL;
77 PPL_Object = NULL;
78 Relation_Symbol = NULL;
79 Variable = NULL;
80 Variable_Stringifier = NULL;
81 Variables_Set = NULL;
82 }
83
84 void
init_cache(JNIEnv * env,jclass & field,const char * name)85 Java_Class_Cache::init_cache(JNIEnv* env, jclass& field, const char* name) {
86 assert(env != NULL);
87 if (field != NULL) {
88 env->DeleteGlobalRef(field);
89 }
90 jclass jni_class = env->FindClass(name);
91 CHECK_RESULT_ASSERT(env, jni_class);
92 field = (jclass) env->NewGlobalRef(jni_class);
93 CHECK_RESULT_ASSERT(env, field);
94 }
95
96 void
init_cache(JNIEnv * env)97 Java_Class_Cache::init_cache(JNIEnv* env) {
98 assert(env != NULL);
99 // Java Virtual Machine pointer.
100 env->GetJavaVM(&jvm);
101 // Non-PPL classes.
102 init_cache(env, Boolean, "java/lang/Boolean");
103 init_cache(env, Integer, "java/lang/Integer");
104 init_cache(env, Long, "java/lang/Long");
105 init_cache(env, Iterator, "java/util/Iterator");
106 // PPL classes.
107 init_cache(env, Artificial_Parameter,
108 "parma_polyhedra_library/Artificial_Parameter");
109 init_cache(env, Artificial_Parameter_Sequence,
110 "parma_polyhedra_library/Artificial_Parameter_Sequence");
111 init_cache(env, Bounded_Integer_Type_Overflow, "parma_polyhedra_library/Bounded_Integer_Type_Overflow");
112 init_cache(env, Bounded_Integer_Type_Representation, "parma_polyhedra_library/Bounded_Integer_Type_Representation");
113 init_cache(env, Bounded_Integer_Type_Width, "parma_polyhedra_library/Bounded_Integer_Type_Width");
114 init_cache(env, By_Reference, "parma_polyhedra_library/By_Reference");
115 init_cache(env, Coefficient, "parma_polyhedra_library/Coefficient");
116 init_cache(env, Congruence, "parma_polyhedra_library/Congruence");
117 init_cache(env, Constraint, "parma_polyhedra_library/Constraint");
118 init_cache(env, Generator, "parma_polyhedra_library/Generator");
119 init_cache(env, Grid_Generator, "parma_polyhedra_library/Grid_Generator");
120 init_cache(env, Generator_Type, "parma_polyhedra_library/Generator_Type");
121 init_cache(env, Grid_Generator_Type,
122 "parma_polyhedra_library/Grid_Generator_Type");
123 init_cache(env, Constraint_System,
124 "parma_polyhedra_library/Constraint_System");
125 init_cache(env, Congruence_System,
126 "parma_polyhedra_library/Congruence_System");
127 init_cache(env, Generator_System,
128 "parma_polyhedra_library/Generator_System");
129 init_cache(env, Grid_Generator_System,
130 "parma_polyhedra_library/Grid_Generator_System");
131 init_cache(env, Linear_Expression,
132 "parma_polyhedra_library/Linear_Expression");
133 init_cache(env, Linear_Expression_Coefficient,
134 "parma_polyhedra_library/Linear_Expression_Coefficient");
135 init_cache(env, Linear_Expression_Difference,
136 "parma_polyhedra_library/Linear_Expression_Difference");
137 init_cache(env, Linear_Expression_Sum,
138 "parma_polyhedra_library/Linear_Expression_Sum");
139 init_cache(env, Linear_Expression_Times,
140 "parma_polyhedra_library/Linear_Expression_Times");
141 init_cache(env, Linear_Expression_Unary_Minus,
142 "parma_polyhedra_library/Linear_Expression_Unary_Minus");
143 init_cache(env, Linear_Expression_Variable,
144 "parma_polyhedra_library/Linear_Expression_Variable");
145 init_cache(env, MIP_Problem_Status,
146 "parma_polyhedra_library/MIP_Problem_Status");
147 init_cache(env, Optimization_Mode,
148 "parma_polyhedra_library/Optimization_Mode");
149 init_cache(env, Pair, "parma_polyhedra_library/Pair");
150 init_cache(env, PIP_Problem_Control_Parameter_Name,
151 "parma_polyhedra_library/PIP_Problem_Control_Parameter_Name");
152 init_cache(env, PIP_Problem_Control_Parameter_Value,
153 "parma_polyhedra_library/PIP_Problem_Control_Parameter_Value");
154 init_cache(env, PIP_Problem_Status,
155 "parma_polyhedra_library/PIP_Problem_Status");
156 init_cache(env, Poly_Con_Relation,
157 "parma_polyhedra_library/Poly_Con_Relation");
158 init_cache(env, Poly_Gen_Relation,
159 "parma_polyhedra_library/Poly_Gen_Relation");
160 init_cache(env, PPL_Object, "parma_polyhedra_library/PPL_Object");
161 init_cache(env, Relation_Symbol, "parma_polyhedra_library/Relation_Symbol");
162 init_cache(env, Variable, "parma_polyhedra_library/Variable");
163 // NOTE: initialization of concrete Variable_Stringifier is responsibility
164 // of static (native) method Variable.setStringifier.
165 init_cache(env, Variables_Set, "parma_polyhedra_library/Variables_Set");
166 }
167
168 void
clear_cache(JNIEnv * env,jclass & field)169 Java_Class_Cache::clear_cache(JNIEnv* env, jclass& field) {
170 assert(env != NULL);
171 if (field != NULL) {
172 env->DeleteGlobalRef(field);
173 field = NULL;
174 }
175 }
176
177 void
clear_cache(JNIEnv * env)178 Java_Class_Cache::clear_cache(JNIEnv* env) {
179 assert(env != NULL);
180 // Clearing the JVM pointer.
181 jvm = NULL;
182 // Non-PPL classes.
183 clear_cache(env, Boolean);
184 clear_cache(env, Integer);
185 clear_cache(env, Long);
186 clear_cache(env, Iterator);
187 // PPL classes.
188 clear_cache(env, Artificial_Parameter);
189 clear_cache(env, Artificial_Parameter_Sequence);
190 clear_cache(env, Bounded_Integer_Type_Overflow);
191 clear_cache(env, Bounded_Integer_Type_Representation);
192 clear_cache(env, Bounded_Integer_Type_Width);
193 clear_cache(env, By_Reference);
194 clear_cache(env, Coefficient);
195 clear_cache(env, Congruence);
196 clear_cache(env, Constraint);
197 clear_cache(env, Generator);
198 clear_cache(env, Grid_Generator);
199 clear_cache(env, Generator_Type);
200 clear_cache(env, Grid_Generator_Type);
201 clear_cache(env, Constraint_System);
202 clear_cache(env, Congruence_System);
203 clear_cache(env, Generator_System);
204 clear_cache(env, Grid_Generator_System);
205 clear_cache(env, Linear_Expression);
206 clear_cache(env, Linear_Expression_Coefficient);
207 clear_cache(env, Linear_Expression_Difference);
208 clear_cache(env, Linear_Expression_Sum);
209 clear_cache(env, Linear_Expression_Times);
210 clear_cache(env, Linear_Expression_Unary_Minus);
211 clear_cache(env, Linear_Expression_Variable);
212 clear_cache(env, MIP_Problem_Status);
213 clear_cache(env, Optimization_Mode);
214 clear_cache(env, PIP_Problem_Status);
215 clear_cache(env, Pair);
216 clear_cache(env, Poly_Con_Relation);
217 clear_cache(env, Poly_Gen_Relation);
218 clear_cache(env, PPL_Object);
219 clear_cache(env, Relation_Symbol);
220 clear_cache(env, Variable);
221 clear_cache(env, Variable_Stringifier);
222 clear_cache(env, Variables_Set);
223 }
224
225 void
handle_exception(JNIEnv * env,const std::overflow_error & e)226 handle_exception(JNIEnv* env, const std::overflow_error& e) {
227 jclass newExcCls
228 = env->FindClass("parma_polyhedra_library/Overflow_Error_Exception");
229 CHECK_RESULT_ASSERT(env, newExcCls);
230 jint ret = env->ThrowNew(newExcCls, e.what());
231 CHECK_RESULT_ABORT(env, ret == 0);
232 }
233
234 void
handle_exception(JNIEnv * env,const std::invalid_argument & e)235 handle_exception(JNIEnv* env, const std::invalid_argument& e) {
236 jclass newExcCls
237 = env->FindClass("parma_polyhedra_library/Invalid_Argument_Exception");
238 CHECK_RESULT_ASSERT(env, newExcCls);
239 jint ret = env->ThrowNew(newExcCls, e.what());
240 CHECK_RESULT_ABORT(env, ret == 0);
241 }
242
243 void
handle_exception(JNIEnv * env,const std::logic_error & e)244 handle_exception(JNIEnv* env, const std::logic_error& e) {
245 jclass newExcCls
246 = env->FindClass("parma_polyhedra_library/Logic_Error_Exception");
247 CHECK_RESULT_ASSERT(env, newExcCls);
248 jint ret = env->ThrowNew(newExcCls, e.what());
249 CHECK_RESULT_ABORT(env, ret == 0);
250 }
251
252 void
handle_exception(JNIEnv * env,const std::length_error & e)253 handle_exception(JNIEnv* env, const std::length_error& e) {
254 jclass newExcCls
255 = env->FindClass("parma_polyhedra_library/Length_Error_Exception");
256 CHECK_RESULT_ASSERT(env, newExcCls);
257 jint ret = env->ThrowNew(newExcCls, e.what());
258 CHECK_RESULT_ABORT(env, ret == 0);
259 }
260
261 void
handle_exception(JNIEnv * env,const std::domain_error & e)262 handle_exception(JNIEnv* env, const std::domain_error& e) {
263 jclass newExcCls
264 = env->FindClass("parma_polyhedra_library/Domain_Error_Exception");
265 CHECK_RESULT_ASSERT(env, newExcCls);
266 jint ret = env->ThrowNew(newExcCls, e.what());
267 CHECK_RESULT_ABORT(env, ret == 0);
268 }
269
270 void
handle_exception(JNIEnv * env,const std::bad_alloc &)271 handle_exception(JNIEnv* env, const std::bad_alloc&) {
272 jclass newExcCls
273 = env->FindClass("java/lang/RuntimeException");
274 CHECK_RESULT_ASSERT(env, newExcCls);
275 jint ret = env->ThrowNew(newExcCls, "Out of memory");
276 CHECK_RESULT_ABORT(env, ret == 0);
277 }
278
279 void
handle_exception(JNIEnv * env,const std::exception & e)280 handle_exception(JNIEnv* env, const std::exception& e) {
281 jclass newExcCls = env->FindClass("java/lang/RuntimeException");
282 CHECK_RESULT_ASSERT(env, newExcCls);
283 jint ret = env->ThrowNew(newExcCls, e.what());
284 CHECK_RESULT_ABORT(env, ret == 0);
285 }
286
287 void
handle_exception(JNIEnv * env,const timeout_exception &)288 handle_exception(JNIEnv* env, const timeout_exception&) {
289 reset_timeout();
290 jclass newExcCls
291 = env->FindClass("parma_polyhedra_library/Timeout_Exception");
292 CHECK_RESULT_ASSERT(env, newExcCls);
293 jint ret = env->ThrowNew(newExcCls, "PPL timeout expired");
294 CHECK_RESULT_ABORT(env, (ret == 0));
295 }
296
297 void
handle_exception(JNIEnv * env,const deterministic_timeout_exception &)298 handle_exception(JNIEnv* env, const deterministic_timeout_exception&) {
299 reset_deterministic_timeout();
300 jclass newExcCls
301 = env->FindClass("parma_polyhedra_library/Timeout_Exception");
302 CHECK_RESULT_ASSERT(env, newExcCls);
303 jint ret = env->ThrowNew(newExcCls, "PPL deterministic timeout expired");
304 CHECK_RESULT_ABORT(env, (ret == 0));
305 }
306
307 void
handle_exception(JNIEnv * env)308 handle_exception(JNIEnv* env) {
309 jclass newExcCls = env->FindClass("java/lang/RuntimeException");
310 CHECK_RESULT_ASSERT(env, newExcCls);
311 jint ret = env->ThrowNew(newExcCls, "PPL bug: unknown exception raised");
312 CHECK_RESULT_ABORT(env, ret == 0);
313 }
314
315 Parma_Polyhedra_Library::Watchdog* p_timeout_object = 0;
316
317 Weightwatch* p_deterministic_timeout_object = 0;
318
319 void
reset_timeout()320 reset_timeout() {
321 if (p_timeout_object) {
322 delete p_timeout_object;
323 p_timeout_object = 0;
324 abandon_expensive_computations = 0;
325 }
326 }
327
328 void
reset_deterministic_timeout()329 reset_deterministic_timeout() {
330 if (p_deterministic_timeout_object) {
331 delete p_deterministic_timeout_object;
332 p_deterministic_timeout_object = 0;
333 abandon_expensive_computations = 0;
334 }
335 }
336
337 jobject
build_java_poly_gen_relation(JNIEnv * env,Poly_Gen_Relation & r)338 build_java_poly_gen_relation(JNIEnv* env, Poly_Gen_Relation& r) {
339 jint j_value = 0;
340 while (r != Poly_Gen_Relation::nothing()) {
341 if (r.implies(Poly_Gen_Relation::subsumes())) {
342 j_value += 1;
343 r = r - Poly_Gen_Relation::subsumes();
344 }
345 }
346 jobject ret = env->NewObject(cached_classes.Poly_Gen_Relation,
347 cached_FMIDs.Poly_Gen_Relation_init_ID,
348 j_value);
349 CHECK_RESULT_THROW(env, ret);
350 return ret;
351 }
352
353 jobject
build_java_poly_con_relation(JNIEnv * env,Poly_Con_Relation & r)354 build_java_poly_con_relation(JNIEnv* env, Poly_Con_Relation& r) {
355 jint j_value = 0;
356 while (r != Poly_Con_Relation::nothing()) {
357 if (r.implies(Poly_Con_Relation::is_disjoint())) {
358 j_value += 1;
359 r = r - Poly_Con_Relation::is_disjoint();
360 }
361 else if (r.implies(Poly_Con_Relation::strictly_intersects())) {
362 j_value += 2;
363 r = r - Poly_Con_Relation::strictly_intersects();
364 }
365 else if (r.implies(Poly_Con_Relation::is_included())) {
366 j_value += 4;
367 r = r - Poly_Con_Relation::is_included();
368 }
369 else if (r.implies(Poly_Con_Relation::saturates())) {
370 j_value += 8;
371 r = r - Poly_Con_Relation::saturates();
372 }
373 }
374 jobject ret = env->NewObject(cached_classes.Poly_Con_Relation,
375 cached_FMIDs.Poly_Con_Relation_init_ID,
376 j_value);
377 CHECK_RESULT_THROW(env, ret);
378 return ret;
379 }
380
381
382 Congruence
build_cxx_congruence(JNIEnv * env,jobject j_congruence)383 build_cxx_congruence(JNIEnv* env, jobject j_congruence) {
384 jobject j_mod
385 = env->GetObjectField(j_congruence, cached_FMIDs.Congruence_mod_ID);
386 jobject j_lhs
387 = env->GetObjectField(j_congruence, cached_FMIDs.Congruence_lhs_ID);
388 jobject j_rhs
389 = env->GetObjectField(j_congruence, cached_FMIDs.Congruence_rhs_ID);
390 PPL_DIRTY_TEMP_COEFFICIENT(ppl_modulus);
391 ppl_modulus = build_cxx_coeff(env, j_mod);
392 Linear_Expression lhs = build_cxx_linear_expression(env, j_lhs);
393 Linear_Expression rhs = build_cxx_linear_expression(env, j_rhs);
394 return (lhs %= rhs) / ppl_modulus;
395 }
396
397 PIP_Tree_Node::Artificial_Parameter
build_cxx_artificial_parameter(JNIEnv * env,jobject j_artificial_parameter)398 build_cxx_artificial_parameter(JNIEnv* env, jobject j_artificial_parameter) {
399 jobject j_le
400 = env->GetObjectField(j_artificial_parameter,
401 cached_FMIDs.Artificial_Parameter_le_ID);
402 jobject j_den
403 = env->GetObjectField(j_artificial_parameter,
404 cached_FMIDs.Artificial_Parameter_den_ID);
405 PPL_DIRTY_TEMP_COEFFICIENT(ppl_den);
406 ppl_den = build_cxx_coeff(env, j_den);
407 Linear_Expression le = build_cxx_linear_expression(env, j_le);
408 PIP_Tree_Node::Artificial_Parameter art_param(le, ppl_den);
409 return art_param;
410 }
411
412 jobject
bool_to_j_boolean_class(JNIEnv * env,const bool value)413 bool_to_j_boolean_class(JNIEnv* env, const bool value) {
414 jobject ret = env->CallStaticObjectMethod(cached_classes.Boolean,
415 cached_FMIDs.Boolean_valueOf_ID,
416 static_cast<jboolean>(value));
417 CHECK_EXCEPTION_ASSERT(env);
418 return ret;
419 }
420
421 jobject
j_long_to_j_long_class(JNIEnv * env,jlong jlong_value)422 j_long_to_j_long_class(JNIEnv* env, jlong jlong_value) {
423 jobject ret = env->CallStaticObjectMethod(cached_classes.Long,
424 cached_FMIDs.Long_valueOf_ID,
425 jlong_value);
426 CHECK_EXCEPTION_THROW(env);
427 return ret;
428 }
429
430 jlong
j_long_class_to_j_long(JNIEnv * env,jobject j_long)431 j_long_class_to_j_long(JNIEnv* env, jobject j_long) {
432 jlong ret = env->CallLongMethod(j_long, cached_FMIDs.Long_longValue_ID);
433 CHECK_EXCEPTION_ASSERT(env);
434 return ret;
435 }
436
437 jobject
j_int_to_j_integer(JNIEnv * env,jint jint_value)438 j_int_to_j_integer(JNIEnv* env, jint jint_value) {
439 jobject ret = env->CallStaticObjectMethod(cached_classes.Integer,
440 cached_FMIDs.Integer_valueOf_ID,
441 jint_value);
442 CHECK_EXCEPTION_THROW(env);
443 return ret;
444 }
445
446 jint
j_integer_to_j_int(JNIEnv * env,jobject j_integer)447 j_integer_to_j_int(JNIEnv* env, jobject j_integer) {
448 jint ret = env->CallIntMethod(j_integer, cached_FMIDs.Integer_intValue_ID);
449 CHECK_EXCEPTION_ASSERT(env);
450 return ret;
451 }
452
453 Variables_Set
build_cxx_variables_set(JNIEnv * env,jobject j_v_set)454 build_cxx_variables_set(JNIEnv* env, jobject j_v_set) {
455 // Get the iterator.
456 jobject j_iter
457 = env->CallObjectMethod(j_v_set, cached_FMIDs.Variables_Set_iterator_ID);
458 CHECK_EXCEPTION_THROW(env);
459 // Get method IDs from cache.
460 jmethodID has_next_ID = cached_FMIDs.Variables_Set_Iterator_has_next_ID;
461 jmethodID next_ID = cached_FMIDs.Variables_Set_Iterator_next_ID;
462 // Initialize an empty set of variables.
463 Variables_Set v_set;
464 jobject j_variable;
465 jboolean has_next_value = env->CallBooleanMethod(j_iter, has_next_ID);
466 while (has_next_value) {
467 j_variable = env->CallObjectMethod(j_iter, next_ID);
468 CHECK_EXCEPTION_ASSERT(env);
469 v_set.insert(build_cxx_variable(env, j_variable));
470 has_next_value = env->CallBooleanMethod(j_iter, has_next_ID);
471 CHECK_EXCEPTION_ASSERT(env);
472 }
473 return v_set;
474 }
475
476 jobject
build_java_variables_set(JNIEnv * env,const Variables_Set & v_set)477 build_java_variables_set(JNIEnv* env, const Variables_Set& v_set) {
478 jobject j_vs = env->NewObject(cached_classes.Variables_Set,
479 cached_FMIDs.Variables_Set_init_ID);
480 CHECK_RESULT_THROW(env, j_vs);
481 for (Variables_Set::const_iterator v_begin = v_set.begin(),
482 v_end = v_set.end(); v_begin != v_end; ++v_begin) {
483 Variable var(*v_begin);
484 jobject j_variable = build_java_variable(env, var);
485 env->CallBooleanMethod(j_vs,
486 cached_FMIDs.Variables_Set_add_ID,
487 j_variable);
488 CHECK_EXCEPTION_THROW(env);
489 }
490 return j_vs;
491 }
492
493 Bounded_Integer_Type_Overflow
build_cxx_bounded_overflow(JNIEnv * env,jobject j_bounded_overflow)494 build_cxx_bounded_overflow(JNIEnv* env, jobject j_bounded_overflow) {
495 jint bounded_overflow
496 = env->CallIntMethod(j_bounded_overflow, cached_FMIDs.Bounded_Integer_Type_Overflow_ordinal_ID);
497 CHECK_EXCEPTION_ASSERT(env);
498 switch (bounded_overflow) {
499 case 0:
500 return OVERFLOW_WRAPS;
501 case 1:
502 return OVERFLOW_UNDEFINED;
503 case 2:
504 return OVERFLOW_IMPOSSIBLE;
505 default:
506 PPL_JAVA_UNEXPECTED;
507 }
508 }
509
510 Bounded_Integer_Type_Representation
build_cxx_bounded_rep(JNIEnv * env,jobject j_bounded_rep)511 build_cxx_bounded_rep(JNIEnv* env, jobject j_bounded_rep) {
512 jint bounded_rep
513 = env->CallIntMethod(j_bounded_rep, cached_FMIDs.Bounded_Integer_Type_Representation_ordinal_ID);
514 CHECK_EXCEPTION_ASSERT(env);
515 switch (bounded_rep) {
516 case 0:
517 return UNSIGNED;
518 case 1:
519 return SIGNED_2_COMPLEMENT;
520 default:
521 PPL_JAVA_UNEXPECTED;
522 }
523 }
524
525 Bounded_Integer_Type_Width
build_cxx_bounded_width(JNIEnv * env,jobject j_bounded_width)526 build_cxx_bounded_width(JNIEnv* env, jobject j_bounded_width) {
527 jint bounded_width
528 = env->CallIntMethod(j_bounded_width, cached_FMIDs.Bounded_Integer_Type_Width_ordinal_ID);
529 CHECK_EXCEPTION_ASSERT(env);
530 switch (bounded_width) {
531 case 0:
532 return BITS_8;
533 case 1:
534 return BITS_16;
535 case 2:
536 return BITS_32;
537 case 3:
538 return BITS_64;
539 case 4:
540 return BITS_128;
541 default:
542 PPL_JAVA_UNEXPECTED;
543 }
544 }
545
546 Relation_Symbol
build_cxx_relsym(JNIEnv * env,jobject j_relsym)547 build_cxx_relsym(JNIEnv* env, jobject j_relsym) {
548 jint rel_sym
549 = env->CallIntMethod(j_relsym, cached_FMIDs.Relation_Symbol_ordinal_ID);
550 CHECK_EXCEPTION_ASSERT(env);
551 switch (rel_sym) {
552 case 0:
553 return LESS_THAN;
554 case 1:
555 return LESS_OR_EQUAL;
556 case 2:
557 return EQUAL;
558 case 3:
559 return GREATER_OR_EQUAL;
560 case 4:
561 return GREATER_THAN;
562 case 5:
563 return NOT_EQUAL;
564 default:
565 PPL_JAVA_UNEXPECTED;
566 }
567 }
568
569 Optimization_Mode
build_cxx_optimization_mode(JNIEnv * env,jobject j_opt_mode)570 build_cxx_optimization_mode(JNIEnv* env, jobject j_opt_mode) {
571 jint opt_mode
572 = env->CallIntMethod(j_opt_mode, cached_FMIDs.Optimization_Mode_ordinal_ID);
573 CHECK_EXCEPTION_ASSERT(env);
574 switch (opt_mode) {
575 case 0:
576 return MINIMIZATION;
577 case 1:
578 return MAXIMIZATION;
579 default:
580 PPL_JAVA_UNEXPECTED;
581 }
582 }
583
584 jobject
build_java_mip_status(JNIEnv * env,const MIP_Problem_Status & mip_status)585 build_java_mip_status(JNIEnv* env, const MIP_Problem_Status& mip_status) {
586 jfieldID fID;
587 switch (mip_status) {
588 case UNFEASIBLE_MIP_PROBLEM:
589 fID = cached_FMIDs.MIP_Problem_Status_UNFEASIBLE_MIP_PROBLEM_ID;
590 break;
591 case UNBOUNDED_MIP_PROBLEM:
592 fID = cached_FMIDs.MIP_Problem_Status_UNBOUNDED_MIP_PROBLEM_ID;
593 break;
594 case OPTIMIZED_MIP_PROBLEM:
595 fID = cached_FMIDs.MIP_Problem_Status_OPTIMIZED_MIP_PROBLEM_ID;
596 break;
597 default:
598 PPL_UNREACHABLE;
599 }
600 return env->GetStaticObjectField(cached_classes.MIP_Problem_Status, fID);
601 }
602
603 jobject
build_java_pip_status(JNIEnv * env,const PIP_Problem_Status & pip_status)604 build_java_pip_status(JNIEnv* env, const PIP_Problem_Status& pip_status) {
605 jfieldID fID;
606 switch (pip_status) {
607 case UNFEASIBLE_PIP_PROBLEM:
608 fID = cached_FMIDs.PIP_Problem_Status_UNFEASIBLE_PIP_PROBLEM_ID;
609 break;
610 case OPTIMIZED_PIP_PROBLEM:
611 fID = cached_FMIDs.PIP_Problem_Status_OPTIMIZED_PIP_PROBLEM_ID;
612 break;
613 default:
614 PPL_UNREACHABLE;
615 }
616 return env->GetStaticObjectField(cached_classes.PIP_Problem_Status, fID);
617 }
618
619 jobject
build_java_optimization_mode(JNIEnv * env,const Optimization_Mode & opt_mode)620 build_java_optimization_mode(JNIEnv* env, const Optimization_Mode& opt_mode) {
621 jfieldID fID;
622 switch (opt_mode) {
623 case MINIMIZATION:
624 fID = cached_FMIDs.Optimization_Mode_MINIMIZATION_ID;
625 break;
626 case MAXIMIZATION:
627 fID = cached_FMIDs.Optimization_Mode_MAXIMIZATION_ID;
628 break;
629 default:
630 PPL_UNREACHABLE;
631 }
632 return env->GetStaticObjectField(cached_classes.Optimization_Mode, fID);
633 }
634
635 MIP_Problem::Control_Parameter_Name
build_cxx_control_parameter_name(JNIEnv * env,jobject j_cp_name)636 build_cxx_control_parameter_name(JNIEnv* env, jobject j_cp_name) {
637 jclass cp_name_class = env->GetObjectClass(j_cp_name);
638 CHECK_RESULT_ASSERT(env, cp_name_class);
639 jmethodID cp_name_ordinal_id
640 = env->GetMethodID(cp_name_class, "ordinal", "()I");
641 CHECK_RESULT_ASSERT(env, cp_name_ordinal_id);
642 jint cp_name = env->CallIntMethod(j_cp_name, cp_name_ordinal_id);
643 CHECK_EXCEPTION_ASSERT(env);
644 if (cp_name == 0)
645 return MIP_Problem::PRICING;
646 else
647 PPL_JAVA_UNEXPECTED;
648 }
649
650 jobject
build_java_control_parameter_name(JNIEnv * env,const MIP_Problem::Control_Parameter_Name & cp_name)651 build_java_control_parameter_name
652 (JNIEnv* env,const MIP_Problem::Control_Parameter_Name& cp_name) {
653 jclass j_cp_name_class
654 = env->FindClass("parma_polyhedra_library/Control_Parameter_Name");
655 CHECK_RESULT_ASSERT(env, j_cp_name_class);
656 jfieldID cp_name_pricing_get_id
657 = env->GetStaticFieldID(j_cp_name_class, "PRICING",
658 "Lparma_polyhedra_library/Control_Parameter_Name;");
659 CHECK_RESULT_ASSERT(env, cp_name_pricing_get_id);
660 if (cp_name == MIP_Problem::PRICING)
661 return env->GetStaticObjectField(j_cp_name_class,
662 cp_name_pricing_get_id);
663 else
664 PPL_UNREACHABLE;
665 }
666
667 MIP_Problem::Control_Parameter_Value
build_cxx_control_parameter_value(JNIEnv * env,jobject j_cp_value)668 build_cxx_control_parameter_value(JNIEnv* env, jobject j_cp_value) {
669 jclass cp_value_class = env->GetObjectClass(j_cp_value);
670 CHECK_RESULT_ASSERT(env, cp_value_class);
671 jmethodID cp_value_ordinal_id
672 = env->GetMethodID(cp_value_class, "ordinal", "()I");
673 CHECK_RESULT_ASSERT(env, cp_value_ordinal_id);
674 jint cp_value = env->CallIntMethod(j_cp_value, cp_value_ordinal_id);
675 CHECK_EXCEPTION_ASSERT(env);
676 switch (cp_value) {
677 case 0:
678 return MIP_Problem::PRICING_STEEPEST_EDGE_FLOAT;
679 case 1:
680 return MIP_Problem::PRICING_STEEPEST_EDGE_EXACT;
681 case 2:
682 return MIP_Problem::PRICING_TEXTBOOK;
683 default:
684 PPL_JAVA_UNEXPECTED;
685 }
686 }
687
688 jobject
build_java_control_parameter_value(JNIEnv * env,const MIP_Problem::Control_Parameter_Value & cp_value)689 build_java_control_parameter_value
690 (JNIEnv* env, const MIP_Problem::Control_Parameter_Value& cp_value) {
691 jclass j_cp_value_class
692 = env->FindClass("parma_polyhedra_library/Control_Parameter_Value");
693 CHECK_RESULT_ASSERT(env, j_cp_value_class);
694 const char* field_name;
695 switch (cp_value) {
696 case MIP_Problem::PRICING_STEEPEST_EDGE_FLOAT:
697 field_name = "PRICING_STEEPEST_EDGE_FLOAT";
698 break;
699 case MIP_Problem::PRICING_STEEPEST_EDGE_EXACT:
700 field_name = "PRICING_STEEPEST_EDGE_EXACT";
701 break;
702 case MIP_Problem::PRICING_TEXTBOOK:
703 field_name = "PRICING_TEXTBOOK";
704 break;
705 default:
706 PPL_UNREACHABLE;
707 }
708 jfieldID fID = env->GetStaticFieldID(j_cp_value_class, field_name,
709 "Lparma_polyhedra_library/Control_Parameter_Value;");
710 CHECK_RESULT_ASSERT(env, fID);
711 return env->GetStaticObjectField(j_cp_value_class, fID);
712 }
713
714 PIP_Problem::Control_Parameter_Name
build_cxx_pip_problem_control_parameter_name(JNIEnv * env,jobject j_cp_name)715 build_cxx_pip_problem_control_parameter_name(JNIEnv* env, jobject j_cp_name) {
716 jclass cp_name_class = env->GetObjectClass(j_cp_name);
717 CHECK_RESULT_ASSERT(env, cp_name_class);
718 jmethodID cp_name_ordinal_id
719 = env->GetMethodID(cp_name_class, "ordinal", "()I");
720 CHECK_RESULT_ASSERT(env, cp_name_ordinal_id);
721 jint cp_name = env->CallIntMethod(j_cp_name, cp_name_ordinal_id);
722 CHECK_EXCEPTION_ASSERT(env);
723 switch (cp_name) {
724 case 0:
725 return PIP_Problem::CUTTING_STRATEGY;
726 case 1:
727 return PIP_Problem::PIVOT_ROW_STRATEGY;
728 default:
729 PPL_JAVA_UNEXPECTED;
730 }
731 }
732
733 jobject
build_java_pip_problem_control_parameter_name(JNIEnv * env,const PIP_Problem::Control_Parameter_Name & cp_name)734 build_java_pip_problem_control_parameter_name
735 (JNIEnv* env, const PIP_Problem::Control_Parameter_Name& cp_name) {
736 jclass j_cp_name_class
737 = env->FindClass("parma_polyhedra_library/PIP_Problem_Control_Parameter_Name");
738 CHECK_RESULT_ASSERT(env, j_cp_name_class);
739 jfieldID cp_name_cutting_strategy_get_id
740 = env->GetStaticFieldID(j_cp_name_class, "CUTTING_STRATEGY",
741 "Lparma_polyhedra_library/PIP_Problem_Control_Parameter_Name;");
742 CHECK_RESULT_ASSERT(env, cp_name_cutting_strategy_get_id);
743 jfieldID cp_name_pivot_row_strategy_get_id
744 = env->GetStaticFieldID(j_cp_name_class, "PIVOT_ROW_STRATEGY",
745 "Lparma_polyhedra_library/PIP_Problem_Control_Parameter_Name;");
746 CHECK_RESULT_ASSERT(env, cp_name_pivot_row_strategy_get_id);
747 switch (cp_name) {
748 case PIP_Problem::CUTTING_STRATEGY:
749 return env->GetStaticObjectField(j_cp_name_class,
750 cp_name_cutting_strategy_get_id);
751 case PIP_Problem::PIVOT_ROW_STRATEGY:
752 return env->GetStaticObjectField(j_cp_name_class,
753 cp_name_pivot_row_strategy_get_id);
754 default:
755 PPL_UNREACHABLE;
756 }
757 }
758
759 PIP_Problem::Control_Parameter_Value
build_cxx_pip_problem_control_parameter_value(JNIEnv * env,jobject j_cp_value)760 build_cxx_pip_problem_control_parameter_value(JNIEnv* env, jobject j_cp_value) {
761 jclass cp_value_class = env->GetObjectClass(j_cp_value);
762 CHECK_RESULT_ASSERT(env, cp_value_class);
763 jmethodID cp_value_ordinal_id
764 = env->GetMethodID(cp_value_class, "ordinal", "()I");
765 CHECK_RESULT_ASSERT(env, cp_value_ordinal_id);
766 jint cp_value = env->CallIntMethod(j_cp_value, cp_value_ordinal_id);
767 CHECK_EXCEPTION_ASSERT(env);
768 switch (cp_value) {
769 case 0:
770 return PIP_Problem::CUTTING_STRATEGY_FIRST;
771 case 1:
772 return PIP_Problem::CUTTING_STRATEGY_DEEPEST;
773 case 2:
774 return PIP_Problem::CUTTING_STRATEGY_ALL;
775 case 3:
776 return PIP_Problem::PIVOT_ROW_STRATEGY_FIRST;
777 case 4:
778 return PIP_Problem::PIVOT_ROW_STRATEGY_MAX_COLUMN;
779 default:
780 PPL_JAVA_UNEXPECTED;
781 }
782 }
783
784 jobject
build_java_pip_problem_control_parameter_value(JNIEnv * env,const PIP_Problem::Control_Parameter_Value & cp_value)785 build_java_pip_problem_control_parameter_value
786 (JNIEnv* env, const PIP_Problem::Control_Parameter_Value& cp_value) {
787 jclass j_cp_value_class
788 = env->FindClass("parma_polyhedra_library/PIP_Problem_Control_Parameter_Value");
789 CHECK_RESULT_ASSERT(env, j_cp_value_class);
790 const char* field_name;
791 switch (cp_value) {
792 case PIP_Problem::CUTTING_STRATEGY_FIRST:
793 field_name = "CUTTING_STRATEGY_FIRST";
794 break;
795 case PIP_Problem::CUTTING_STRATEGY_DEEPEST:
796 field_name = "CUTTING_STRATEGY_DEEPEST";
797 break;
798 case PIP_Problem::CUTTING_STRATEGY_ALL:
799 field_name = "CUTTING_STRATEGY_ALL";
800 break;
801 case PIP_Problem::PIVOT_ROW_STRATEGY_FIRST:
802 field_name = "PIVOT_ROW_STRATEGY_FIRST";
803 break;
804 case PIP_Problem::PIVOT_ROW_STRATEGY_MAX_COLUMN:
805 field_name = "PIVOT_ROW_STRATEGY_MAX_COLUMN";
806 break;
807 default:
808 PPL_UNREACHABLE;
809 }
810 jfieldID fID = env->GetStaticFieldID(j_cp_value_class, field_name,
811 "Lparma_polyhedra_library/PIP_Problem_Control_Parameter_Value;");
812 CHECK_RESULT_ASSERT(env, fID);
813 return env->GetStaticObjectField(j_cp_value_class, fID);
814 }
815
816 Constraint
build_cxx_constraint(JNIEnv * env,jobject j_constraint)817 build_cxx_constraint(JNIEnv* env, jobject j_constraint) {
818 jobject lhs_value
819 = env->GetObjectField(j_constraint, cached_FMIDs.Constraint_lhs_ID);
820 jobject rhs_value
821 = env->GetObjectField(j_constraint, cached_FMIDs.Constraint_rhs_ID);
822 jobject kind
823 = env->GetObjectField(j_constraint, cached_FMIDs.Constraint_kind_ID);
824 Linear_Expression first_le = build_cxx_linear_expression(env, lhs_value);
825 Linear_Expression second_le = build_cxx_linear_expression(env, rhs_value);
826 jint rel_sym
827 = env->CallIntMethod(kind, cached_FMIDs.Relation_Symbol_ordinal_ID);
828 CHECK_EXCEPTION_ASSERT(env);
829 switch (rel_sym) {
830 case 0:
831 return Constraint(first_le < second_le);
832 case 1:
833 return Constraint(first_le <= second_le);
834 case 2:
835 return Constraint(first_le == second_le);
836 case 3:
837 return Constraint(first_le >= second_le);
838 case 4:
839 return Constraint(first_le > second_le);
840 default:
841 PPL_JAVA_UNEXPECTED;
842 }
843 }
844
845 Linear_Expression
build_cxx_linear_expression(JNIEnv * env,jobject j_le)846 build_cxx_linear_expression(JNIEnv* env, jobject j_le) {
847 jfieldID fID;
848 jclass current_class = env->GetObjectClass(j_le);
849 // LE_Variable
850 if (env->IsAssignableFrom(current_class,
851 cached_classes.Linear_Expression_Variable)) {
852 jmethodID mID = cached_FMIDs.Linear_Expression_Variable_var_id_ID;
853 jlong var_id = env->CallLongMethod(j_le, mID);
854 return Linear_Expression(Variable(var_id));
855 }
856 // LE_Coefficient
857 if (env->IsAssignableFrom(current_class,
858 cached_classes.Linear_Expression_Coefficient)) {
859 fID = cached_FMIDs.Linear_Expression_Coefficient_coeff_ID;
860 jobject ppl_coeff = env->GetObjectField(j_le, fID);
861 return Linear_Expression(build_cxx_coeff(env, ppl_coeff));
862 }
863 // LE_Sum
864 if (env->IsAssignableFrom(current_class,
865 cached_classes.Linear_Expression_Sum)) {
866 fID = cached_FMIDs.Linear_Expression_Sum_lhs_ID;
867 jobject l_value = env->GetObjectField(j_le, fID);
868 fID = cached_FMIDs.Linear_Expression_Sum_rhs_ID;
869 jobject r_value = env->GetObjectField(j_le, fID);
870 return build_cxx_linear_expression(env, l_value)
871 + build_cxx_linear_expression(env, r_value);
872 }
873 // LE_Times
874 if (env->IsAssignableFrom(current_class,
875 cached_classes.Linear_Expression_Times)) {
876 fID = cached_FMIDs.Linear_Expression_Times_coeff_ID;
877 jobject coeff_value = env->GetObjectField(j_le, fID);
878 fID = cached_FMIDs.Linear_Expression_Times_lin_expr_ID;
879 jobject le_value = env->GetObjectField(j_le, fID);
880 return build_cxx_coeff(env, coeff_value)
881 * build_cxx_linear_expression(env, le_value);
882 }
883 // LE_Difference
884 if (env->IsAssignableFrom(current_class,
885 cached_classes.Linear_Expression_Difference)) {
886 fID = cached_FMIDs.Linear_Expression_Difference_lhs_ID;
887 jobject l_value = env->GetObjectField(j_le,fID);
888 fID = cached_FMIDs.Linear_Expression_Difference_rhs_ID;
889 jobject r_value = env->GetObjectField(j_le, fID);
890 return build_cxx_linear_expression(env, l_value)
891 - build_cxx_linear_expression(env, r_value);
892 }
893 // LE_Unary_Minus
894 if (env->IsAssignableFrom(current_class,
895 cached_classes.Linear_Expression_Unary_Minus)) {
896 fID = cached_FMIDs.Linear_Expression_Unary_Minus_arg_ID;
897 jobject le_value = env->GetObjectField(j_le, fID);
898 return -build_cxx_linear_expression(env, le_value);
899 }
900 // All cases dealt with above.
901 PPL_JAVA_UNEXPECTED;
902 }
903
904 Generator
build_cxx_generator(JNIEnv * env,jobject j_generator)905 build_cxx_generator(JNIEnv* env, jobject j_generator) {
906 jobject j_le
907 = env->GetObjectField(j_generator, cached_FMIDs.Generator_le_ID);
908 jobject generator_type
909 = env->GetObjectField(j_generator, cached_FMIDs.Generator_gt_ID);
910 jint generator_type_ordinal
911 = env->CallIntMethod(generator_type,
912 cached_FMIDs.Generator_Type_ordinal_ID);
913 CHECK_EXCEPTION_ASSERT(env);
914 switch (generator_type_ordinal) {
915 case 0:
916 return line(build_cxx_linear_expression(env, j_le));
917 case 1:
918 return ray(build_cxx_linear_expression(env, j_le));
919 case 2:
920 {
921 jobject j_div
922 = env->GetObjectField(j_generator, cached_FMIDs.Generator_div_ID);
923 return point(build_cxx_linear_expression(env, j_le),
924 build_cxx_coeff(env, j_div));
925 }
926 case 3:
927 {
928 jobject j_div
929 = env->GetObjectField(j_generator, cached_FMIDs.Generator_div_ID);
930 return closure_point(build_cxx_linear_expression(env, j_le),
931 build_cxx_coeff(env, j_div));
932 }
933 default:
934 PPL_JAVA_UNEXPECTED;
935 }
936 }
937
938 Grid_Generator
build_cxx_grid_generator(JNIEnv * env,jobject j_grid_generator)939 build_cxx_grid_generator(JNIEnv* env, jobject j_grid_generator) {
940 jobject j_le
941 = env->GetObjectField(j_grid_generator, cached_FMIDs.Grid_Generator_le_ID);
942 jobject grid_generator_type
943 = env->GetObjectField(j_grid_generator, cached_FMIDs.Grid_Generator_gt_ID);
944 jint grid_generator_type_ordinal
945 = env->CallIntMethod(grid_generator_type,
946 cached_FMIDs.Grid_Generator_Type_ordinal_ID);
947 CHECK_EXCEPTION_ASSERT(env);
948 switch (grid_generator_type_ordinal) {
949 case 0:
950 return grid_line(build_cxx_linear_expression(env, j_le));
951 case 1:
952 {
953 jobject j_div = env->GetObjectField(j_grid_generator,
954 cached_FMIDs.Grid_Generator_div_ID);
955 return parameter(build_cxx_linear_expression(env, j_le),
956 build_cxx_coeff(env, j_div));
957 }
958 case 2:
959 {
960 jobject j_div = env->GetObjectField(j_grid_generator,
961 cached_FMIDs.Grid_Generator_div_ID);
962 return grid_point(build_cxx_linear_expression(env, j_le),
963 build_cxx_coeff(env, j_div));
964 }
965 default:
966 PPL_JAVA_UNEXPECTED;
967 }
968 }
969
970 jobject
build_java_linear_expression_coefficient(JNIEnv * env,const Coefficient & c)971 build_java_linear_expression_coefficient(JNIEnv* env, const Coefficient& c) {
972 jobject j_coeff = build_java_coeff(env, c);
973 jobject ret
974 = env->NewObject(cached_classes.Linear_Expression_Coefficient,
975 cached_FMIDs.Linear_Expression_Coefficient_init_ID,
976 j_coeff);
977 CHECK_RESULT_THROW(env, ret);
978 return ret;
979 }
980
981 void
set_generator(JNIEnv * env,jobject dst,jobject src)982 set_generator(JNIEnv* env, jobject dst, jobject src) {
983 jobject src_gt = env->GetObjectField(src, cached_FMIDs.Generator_gt_ID);
984 env->SetObjectField(dst, cached_FMIDs.Generator_gt_ID, src_gt);
985 jobject src_le = env->GetObjectField(src, cached_FMIDs.Generator_le_ID);
986 env->SetObjectField(dst, cached_FMIDs.Generator_le_ID, src_le);
987 jobject src_div = env->GetObjectField(src, cached_FMIDs.Generator_div_ID);
988 env->SetObjectField(dst, cached_FMIDs.Generator_div_ID, src_div);
989 }
990
991 void
set_pair_element(JNIEnv * env,jobject dst_pair,int arg,jobject src)992 set_pair_element(JNIEnv* env, jobject dst_pair, int arg, jobject src) {
993 switch (arg) {
994 case 0:
995 env->SetObjectField(dst_pair, cached_FMIDs.Pair_first_ID, src);
996 break;
997 case 1:
998 env->SetObjectField(dst_pair, cached_FMIDs.Pair_second_ID, src);
999 break;
1000 default:
1001 PPL_JAVA_UNEXPECTED;
1002 }
1003 }
1004
1005 jobject
get_pair_element(JNIEnv * env,int arg,jobject j_pair)1006 get_pair_element(JNIEnv* env, int arg, jobject j_pair) {
1007 switch (arg) {
1008 case 0:
1009 return env->GetObjectField(j_pair, cached_FMIDs.Pair_first_ID);
1010 case 1:
1011 return env->GetObjectField(j_pair, cached_FMIDs.Pair_second_ID);
1012 default:
1013 PPL_JAVA_UNEXPECTED;
1014 }
1015 }
1016
1017 jobject
build_java_constraint(JNIEnv * env,const Constraint & c)1018 build_java_constraint(JNIEnv* env, const Constraint& c) {
1019 jobject lhs = build_linear_expression(env, c);
1020 jobject rhs
1021 = build_java_linear_expression_coefficient(env, -c.inhomogeneous_term());
1022 jfieldID fID;
1023 switch (c.type()) {
1024 case Constraint::EQUALITY:
1025 fID = cached_FMIDs.Relation_Symbol_EQUAL_ID;
1026 break;
1027 case Constraint::NONSTRICT_INEQUALITY:
1028 fID = cached_FMIDs.Relation_Symbol_GREATER_OR_EQUAL_ID;
1029 break;
1030 case Constraint::STRICT_INEQUALITY:
1031 fID = cached_FMIDs.Relation_Symbol_GREATER_THAN_ID;
1032 break;
1033 default:
1034 PPL_UNREACHABLE;
1035 }
1036 jobject relation
1037 = env->GetStaticObjectField(cached_classes.Relation_Symbol, fID);
1038 jobject ret = env->NewObject(cached_classes.Constraint,
1039 cached_FMIDs.Constraint_init_ID,
1040 lhs, relation, rhs);
1041 CHECK_RESULT_THROW(env, ret);
1042 return ret;
1043 }
1044
1045 jobject
build_java_congruence(JNIEnv * env,const Congruence & cg)1046 build_java_congruence(JNIEnv* env, const Congruence& cg) {
1047 jobject j_mod = build_java_coeff(env, cg.modulus());
1048 jobject j_lhs = build_linear_expression(env, cg);
1049 jobject j_rhs
1050 = build_java_linear_expression_coefficient(env, -cg.inhomogeneous_term());
1051 jobject ret = env->NewObject(cached_classes.Congruence,
1052 cached_FMIDs.Congruence_init_ID,
1053 j_lhs, j_rhs, j_mod);
1054 CHECK_RESULT_THROW(env, ret);
1055 return ret;
1056 }
1057
1058 jobject
build_java_generator(JNIEnv * env,const Generator & g)1059 build_java_generator(JNIEnv* env, const Generator& g) {
1060 jobject j_g_le = build_linear_expression(env, g);
1061 jobject ret;
1062 switch (g.type()) {
1063 case Generator::LINE:
1064 ret = env->CallStaticObjectMethod(cached_classes.Generator,
1065 cached_FMIDs.Generator_line_ID,
1066 j_g_le);
1067 break;
1068 case Generator::RAY:
1069 ret = env->CallStaticObjectMethod(cached_classes.Generator,
1070 cached_FMIDs.Generator_ray_ID,
1071 j_g_le);
1072 break;
1073 case Generator::POINT:
1074 {
1075 const Coefficient& divisor = g.divisor();
1076 jobject j_div = build_java_coeff(env, divisor);
1077 ret = env->CallStaticObjectMethod(cached_classes.Generator,
1078 cached_FMIDs.Generator_point_ID,
1079 j_g_le, j_div);
1080 break;
1081 }
1082 case Generator::CLOSURE_POINT:
1083 {
1084 const Coefficient& divisor = g.divisor();
1085 jobject j_div = build_java_coeff(env, divisor);
1086 ret = env->CallStaticObjectMethod(cached_classes.Generator,
1087 cached_FMIDs.Generator_closure_point_ID,
1088 j_g_le, j_div);
1089 break;
1090 }
1091 default:
1092 PPL_UNREACHABLE;
1093 }
1094 CHECK_EXCEPTION_THROW(env);
1095 return ret;
1096 }
1097
1098 jobject
build_java_grid_generator(JNIEnv * env,const Grid_Generator & g)1099 build_java_grid_generator(JNIEnv* env, const Grid_Generator& g) {
1100 jobject j_g_le = build_linear_expression(env, g);
1101 jobject ret;
1102 switch (g.type()) {
1103 case Grid_Generator::LINE:
1104 ret = env->CallStaticObjectMethod(cached_classes.Grid_Generator,
1105 cached_FMIDs.Grid_Generator_grid_line_ID,
1106 j_g_le);
1107 break;
1108 case Grid_Generator::PARAMETER:
1109 {
1110 const Coefficient& divisor = g.divisor();
1111 jobject j_div = build_java_coeff(env, divisor);
1112 ret = env->CallStaticObjectMethod(cached_classes.Grid_Generator,
1113 cached_FMIDs.Grid_Generator_parameter_ID,
1114 j_g_le, j_div);
1115 break;
1116 }
1117 case Grid_Generator::POINT:
1118 {
1119 const Coefficient& divisor = g.divisor();
1120 jobject j_div = build_java_coeff(env, divisor);
1121 ret = env->CallStaticObjectMethod(cached_classes.Grid_Generator,
1122 cached_FMIDs.Grid_Generator_grid_point_ID,
1123 j_g_le, j_div);
1124 break;
1125 }
1126 default:
1127 PPL_UNREACHABLE;
1128 }
1129 CHECK_EXCEPTION_THROW(env);
1130 return ret;
1131 }
1132
1133 jobject
build_java_constraint_system(JNIEnv * env,const Constraint_System & cs)1134 build_java_constraint_system(JNIEnv* env, const Constraint_System& cs) {
1135 jobject j_cs = env->NewObject(cached_classes.Constraint_System,
1136 cached_FMIDs.Constraint_System_init_ID);
1137 CHECK_RESULT_THROW(env, j_cs);
1138 for (Constraint_System::const_iterator v_begin = cs.begin(),
1139 v_end = cs.end(); v_begin != v_end; ++v_begin) {
1140 jobject j_constraint = build_java_constraint(env, *v_begin);
1141 env->CallBooleanMethod(j_cs,
1142 cached_FMIDs.Constraint_System_add_ID,
1143 j_constraint);
1144 CHECK_EXCEPTION_THROW(env);
1145 }
1146 return j_cs;
1147 }
1148
1149 jobject
build_java_generator_system(JNIEnv * env,const Generator_System & gs)1150 build_java_generator_system(JNIEnv* env, const Generator_System& gs) {
1151 jobject j_gs = env->NewObject(cached_classes.Generator_System,
1152 cached_FMIDs.Generator_System_init_ID);
1153 CHECK_RESULT_THROW(env, j_gs);
1154 for (Generator_System::const_iterator v_begin = gs.begin(),
1155 v_end = gs.end(); v_begin != v_end; ++v_begin) {
1156 jobject j_generator = build_java_generator(env, *v_begin);
1157 env->CallBooleanMethod(j_gs,
1158 cached_FMIDs.Generator_System_add_ID,
1159 j_generator);
1160 CHECK_EXCEPTION_THROW(env);
1161 }
1162 return j_gs;
1163 }
1164
1165 jobject
build_java_grid_generator_system(JNIEnv * env,const Grid_Generator_System & gs)1166 build_java_grid_generator_system(JNIEnv* env,
1167 const Grid_Generator_System& gs) {
1168 jobject j_gs = env->NewObject(cached_classes.Grid_Generator_System,
1169 cached_FMIDs.Grid_Generator_System_init_ID);
1170 CHECK_RESULT_THROW(env, j_gs);
1171 for (Grid_Generator_System::const_iterator v_begin = gs.begin(),
1172 v_end = gs.end(); v_begin != v_end; ++v_begin) {
1173 jobject j_generator = build_java_grid_generator(env, *v_begin);
1174 env->CallBooleanMethod(j_gs,
1175 cached_FMIDs.Grid_Generator_System_add_ID,
1176 j_generator);
1177 CHECK_EXCEPTION_THROW(env);
1178 }
1179 return j_gs;
1180 }
1181
1182 jobject
build_java_congruence_system(JNIEnv * env,const Congruence_System & cgs)1183 build_java_congruence_system(JNIEnv* env, const Congruence_System& cgs) {
1184 jobject j_cgs = env->NewObject(cached_classes.Congruence_System,
1185 cached_FMIDs.Congruence_System_init_ID);
1186 CHECK_RESULT_THROW(env, j_cgs);
1187 for (Congruence_System::const_iterator v_begin = cgs.begin(),
1188 v_end = cgs.end(); v_begin != v_end; ++v_begin) {
1189 jobject j_congruence = build_java_congruence(env,*v_begin);
1190 env->CallBooleanMethod(j_cgs,
1191 cached_FMIDs.Congruence_System_add_ID,
1192 j_congruence);
1193 CHECK_EXCEPTION_THROW(env);
1194 }
1195 return j_cgs;
1196 }
1197
1198 jobject
build_java_artificial_parameter(JNIEnv * env,const PIP_Tree_Node::Artificial_Parameter & art)1199 build_java_artificial_parameter
1200 (JNIEnv* env, const PIP_Tree_Node::Artificial_Parameter& art) {
1201 jobject j_le = build_linear_expression(env, art);
1202 jobject j_den = build_java_coeff(env, art.denominator());
1203 jobject ret = env->NewObject(cached_classes.Artificial_Parameter,
1204 cached_FMIDs.Artificial_Parameter_init_ID,
1205 j_le, j_den);
1206 CHECK_RESULT_THROW(env, ret);
1207 return ret;
1208 }
1209
1210 void
Java_Variable_output_function(std::ostream & s,Variable v)1211 Java_Variable_output_function(std::ostream& s, Variable v) {
1212 // Use cached Java Virtual Machine pointer to retrieve JNI env.
1213 JavaVM* jvm = cached_classes.jvm;
1214 JNIEnv *env = 0;
1215 jvm->AttachCurrentThread((void **)&env, NULL);
1216 CHECK_EXCEPTION_ASSERT(env);
1217 // Retrieve stringifier object.
1218 jclass var_class = cached_classes.Variable;
1219 jfieldID fID = cached_FMIDs.Variable_stringifier_ID;
1220 jobject stringifier = env->GetStaticObjectField(var_class, fID);
1221 CHECK_RESULT_THROW(env, stringifier);
1222 // Use it to get the Java string for the variable.
1223 jmethodID mID = cached_FMIDs.Variable_Stringifier_stringify_ID;
1224 #ifndef NDEBUG
1225 {
1226 // Dynamically retrieve stringifier class and use it to compute
1227 // the corresponding method ID, so as to compare it with cached one.
1228 jclass dyn_class = env->GetObjectClass(stringifier);
1229 jmethodID dyn_mID = env->GetMethodID(dyn_class, "stringify",
1230 "(J)Ljava/lang/String;");
1231 CHECK_RESULT_ASSERT(env, mID == dyn_mID);
1232 }
1233 #endif // #ifndef NDEBUG
1234 jlong j_var_id = v.id();
1235 jstring bi_string
1236 = (jstring) env->CallObjectMethod(stringifier, mID, j_var_id);
1237 CHECK_EXCEPTION_THROW(env);
1238 // Convert the string and print it on C++ stream.
1239 const char* nativeString = env->GetStringUTFChars(bi_string, 0);
1240 CHECK_RESULT_THROW(env, nativeString);
1241 s << nativeString;
1242 env->ReleaseStringUTFChars(bi_string, nativeString);
1243 }
1244
1245 } // namespace Java
1246
1247 } // namespace Interfaces
1248
1249 } // namespace Parma_Polyhedra_Library
1250