GNU PROLOG with UTF8 support
fd_to_c.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------*
2  * GNU Prolog *
3  * *
4  * Part : FD constraint solver *
5  * File : fd_to_c.h *
6  * Descr.: FD to C macros - header file *
7  * Author: Daniel Diaz *
8  * *
9  * Copyright (C) 1999-2015 Daniel Diaz *
10  * *
11  * This file is part of GNU Prolog *
12  * *
13  * GNU Prolog is free software: you can redistribute it and/or *
14  * modify it under the terms of either: *
15  * *
16  * - the GNU Lesser General Public License as published by the Free *
17  * Software Foundation; either version 3 of the License, or (at your *
18  * option) any later version. *
19  * *
20  * or *
21  * *
22  * - the GNU General Public License as published by the Free *
23  * Software Foundation; either version 2 of the License, or (at your *
24  * option) any later version. *
25  * *
26  * or both in parallel, as here. *
27  * *
28  * GNU Prolog is distributed in the hope that it will be useful, *
29  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
31  * General Public License for more details. *
32  * *
33  * You should have received copies of the GNU General Public License and *
34  * the GNU Lesser General Public License along with this program. If *
35  * not, see http://www.gnu.org/licenses/. *
36  *-------------------------------------------------------------------------*/
37 
38 
39 
40 #ifndef _FD_TO_C_H
41 #define _FD_TO_C_H
42 
43 #include <stdio.h>
44 
45 #include "../EnginePl/pl_params.h"
46 #include "../EnginePl/wam_archi.h"
47 #include "engine_fd.h"
48 
49 
50 
51 
52 /*---------------------------------*
53  * Constants *
54  *---------------------------------*/
55 
56 
57 
58  /* Environment Frame */
59 
60 #define Frame_Variable(fv) ((WamWord *)(AF[fv]))
61 #define Frame_Range_Parameter(fp) ((Range *) (AF[fp]))
62 #define Frame_Term_Parameter(fp) ((int) (AF[fp]))
63 #define Frame_List_Parameter(fp) ((WamWord *)(AF[fp]))
64 
65 
66 #define chain_min CHAIN_NB_MIN
67 #define chain_max CHAIN_NB_MAX
68 #define chain_min_max CHAIN_NB_MIN_MAX
69 #define chain_dom CHAIN_NB_DOM
70 #define chain_val CHAIN_NB_VAL
71 
72 
73 
74 
75 /*---------------------------------*
76  * Type Definitions *
77  *---------------------------------*/
78 
79 /*---------------------------------*
80  * Global Variables *
81  *---------------------------------*/
82 
83 /*---------------------------------*
84  * Function Prototypes *
85  *---------------------------------*/
86 
87 
88 
89 
90 /*---------------------------------*
91  * Auxiliary engine macros *
92  *---------------------------------*/
93 
94 #define DivDn(x, y) ((x) / (y))
95 #define DivUp(x, y) (((x) + (y) - 1) / (y))
96 
97 
98 #define R(r_no) rr##r_no
99 
100  /* Interface with Prolog clauses instructions */
101 
102 #define fd_create_a_frame(nb_arg) \
103  AF = CS; \
104  CS += nb_arg;
105 
106 
107 
108 
109 #define fd_int_in_a_frame(arg, offset) \
110  AF[offset] = (WamWord) Pl_Fd_Prolog_To_Value(fd_##arg);
111 
112 
113 
114 
115 #define fd_range_in_a_frame(arg, offset) \
116  AF[offset] = (WamWord) Pl_Fd_Prolog_To_Range(fd_##arg);
117 
118 
119 
120 
121 #define fd_fdv_in_a_frame(arg, offset) \
122  AF[offset] = (WamWord) Pl_Fd_Prolog_To_Fd_Var(fd_##arg, TRUE);
123 
124 
125 
126 
127 #define fd_fdv_in_a_frame(arg, offset) \
128  AF[offset] = (WamWord) Pl_Fd_Prolog_To_Fd_Var(fd_##arg, TRUE);
129 
130 
131 
132 
133 #define fd_any_in_a_frame(arg, offset) \
134  AF[offset] = (WamWord) fd_##arg;
135 
136 
137 
138 
139 #define fd_l_int_in_a_frame(arg, offset) \
140  AF[offset] = (WamWord) Pl_Fd_Prolog_To_Array_Int(fd_##arg);
141 
142 
143 
144 
145 #define fd_l_range_in_a_frame(arg, offset) \
146  printf("fd_l_range_in_a_frame not yet implemented...\n");
147 
148 
149 
150 
151 #define fd_l_fdv_in_a_frame(arg, offset) \
152  AF[offset] = (WamWord) Pl_Fd_Prolog_To_Array_Fdv(fd_##arg, TRUE);
153 
154 
155 
156 
157 #define fd_l_any_in_a_frame(arg, offset) \
158  AF[offset] = (WamWord) Pl_Fd_Prolog_To_Array_Any(fd_##arg);
159 
160 
161 
162 
163 #define fd_cf_in_a_frame(offset) \
164  AF[offset] = (WamWord) CF;
165 
166 
167 
168 
169 #define fd_call_internal(fct_name) \
170  if (!fct_name(AF)) \
171  { \
172  ret_val = FALSE; \
173  goto lab_exit; \
174  }
175 
176 
177 
178 
179 #define fd_call_internal_and_test_switch_simple(fct_name) \
180 { \
181  PlLong (*fct) () = (PlLong (*)()) fct_name(AF); \
182  \
183  if (fct == (PlLong (*)()) FALSE) \
184  { \
185  ret_val = FALSE; \
186  goto lab_exit; \
187  } \
188  if (fct != (PlLong (*)()) TRUE)/* FD switch case triggered */ \
189  { \
190  if ((*fct) (AF) == FALSE) \
191  { \
192  ret_val = FALSE; \
193  goto lab_exit; \
194  } \
195  } \
196 }
197 
198 
199 
200 
201 #define fd_call_internal_and_test_switch(fct_name) \
202 { \
203  PlLong (*fct) () = (PlLong (*)()) fct_name(AF); \
204  \
205  if (fct == (PlLong (*)()) FALSE) \
206  { \
207  ret_val = FALSE; \
208  goto lab_exit; \
209  } \
210  if (fct != (PlLong (*)()) TRUE)/* FD switch case triggered */ \
211  { \
212  if ((*fct) (AF) == FALSE) \
213  { \
214  ret_val = FALSE; \
215  goto lab_exit; \
216  } \
217  \
218  Pl_Fd_Stop_Constraint(CF); \
219  } \
220 }
221 
222 
223 
224 
225 
226 
227 #define fd_stop_constraint(offset) \
228  if (AF[offset]) \
229  Pl_Fd_Stop_Constraint((WamWord *) (AF[offset]));
230 
231 
232 
233 
234  /* Install instructions */
235 
236 #define fd_create_c_frame(fct_name, tell_fv, optim2) \
237  CF = Pl_Fd_Create_C_Frame(fct_name, AF, \
238  (tell_fv == -1) ? NULL : Frame_Variable(tell_fv), \
239  optim2);
240 
241 
242 
243 
244 #define fd_add_dependency(fv, ch) \
245  Pl_Fd_Add_Dependency(Frame_Variable(fv), chain_##ch, CF);
246 
247 
248 
249 
250 #define fd_add_list_dependency(fv, ch) \
251  Pl_Fd_Add_List_Dependency(Frame_Variable(fv), chain_##ch, CF);
252 
253 
254 
255 
256  /* Constraint instructions */
257 
258 #define fd_before_add_constraint \
259  Pl_Fd_Before_Add_Cstr();
260 
261 
262 
263 
264 #define fd_after_add_constraint \
265  ret_val = Pl_Fd_After_Add_Cstr(ret_val); /* always followed by fd_return */
266 
267 
268 
269 
270 #define fd_allocate \
271 { \
272  WamWord *save_CS = CS; \
273  CS += pl_vec_size;
274 
275 
276 
277 
278 #define fd_deallocate \
279  CS = save_CS; \
280 }
281 
282 
283 
284 
285 #define fd_tell_value(fv, t) \
286 { \
287  fdv_adr = Frame_Variable(fv); \
288  if (!Pl_Fd_Tell_Value(fdv_adr, t)) \
289  { \
290  ret_val = FALSE; \
291  goto lab_exit; \
292  } \
293 }
294 
295 
296 
297 
298 #define fd_tell_not_value(fv, t) \
299 { \
300  fdv_adr = Frame_Variable(fv); \
301  if (!Pl_Fd_Tell_Not_Value(fdv_adr, t)) \
302  { \
303  ret_val = FALSE; \
304  goto lab_exit; \
305  } \
306 }
307 
308 
309 
310 
311 #define fd_tell_interval(fv, t_min, t_max) \
312 { \
313  fdv_adr = Frame_Variable(fv); \
314  if (!Pl_Fd_Tell_Interval(fdv_adr, t_min, t_max)) \
315  { \
316  ret_val = FALSE; \
317  goto lab_exit; \
318  } \
319 }
320 
321 
322 
323 
324 #define fd_tell_range(fv, r) \
325 { \
326  fdv_adr = Frame_Variable(fv); \
327  if (!Pl_Fd_Tell_Range(fdv_adr, &R(r))) \
328  { \
329  ret_val = FALSE; \
330  goto lab_exit; \
331  } \
332 }
333 
334 
335 
336 
337 #define fd_check_fct(fct) \
338  if (!fct) \
339  { \
340  ret_val = FALSE; \
341  goto lab_exit; \
342  }
343 
344 
345  /* Tests */
346 
347 #define fd_test_exit_condition(t) \
348  if (t) \
349  goto lab_exit;
350 
351 
352 
353 #define fd_test_fail_condition(t) \
354  if (!t) \
355  { \
356  ret_val = FALSE; \
357  goto lab_exit; \
358  }
359 
360 
361 
362 
363 
364 #define fd_test_switch_condition(t, fct_name) \
365  if (t) \
366  { \
367  ret_val = (PlLong) fct_name; \
368  goto lab_exit; \
369  }
370 
371 
372 
373 
374  /* Range */
375 
376 #define fd_range_interval(r, t_min, t_max) \
377  Range_Init_Interval(&R(r), t_min, t_max);
378 
379 
380 
381 
382 #define fd_load_range(r, fp) \
383  R(r).vec = NULL; \
384  Pl_Range_Copy(&R(r), Frame_Range_Parameter(fp));
385 
386 
387 
388 
389 #define fd_load_dom(r, fv) \
390  fdv_adr = Frame_Variable(fv); \
391  R(r).vec = NULL; \
392  Pl_Range_Copy(&R(r), Range(fdv_adr));
393 
394 
395 
396 
397 #define fd_range_union(r, r1) \
398  Pl_Range_Union(&R(r), &R(r1));
399 
400 
401 
402 
403 #define fd_range_inter(r, r1) \
404  Pl_Range_Inter(&R(r), &R(r1));
405 
406 
407 
408 
409 #define fd_range_compl(r) \
410  Pl_Range_Compl(&R(r));
411 
412 
413 
414 
415 #define fd_range_empty(r) \
416  R(r).vec = NULL; \
417  Set_To_Empty(&R(r));
418 
419 
420 
421 
422 #define fd_range_full(r) \
423  Range_Init_Interval(&R(r), 0, INTERVAL_MAX_INTEGER);
424 
425 
426 
427 
428 #define fd_range_set_value(r, t) \
429  Pl_Range_Set_Value(&R(r), t);
430 
431 
432 
433 
434 #define fd_range_reset_value(r, t) \
435  Pl_Range_Reset_Value(&R(r), t);
436 
437 
438 
439 
440 #define fd_range_add_range(r, r1) \
441  Pl_Range_Add_Range(&R(r), &R(r1));
442 
443 
444 
445 
446 #define fd_range_sub_range(r, r1) \
447  Pl_Range_Sub_Range(&R(r), &R(r1));
448 
449 
450 
451 
452 #define fd_range_mul_range(r, r1) \
453  Pl_Range_Mul_Range(&R(r), &R(r1));
454 
455 
456 
457 
458 #define fd_range_div_range(r, r1) \
459  Pl_Range_Div_Range(&R(r), &R(r1));
460 
461 
462 
463 
464 #define fd_range_mod_range(r, r1) \
465  Pl_Range_Mod_Range(&R(r), &R(r1));
466 
467 
468 
469 
470 #define fd_range_add_value(r, t) \
471  Pl_Range_Add_Value(&R(r), t);
472 
473 
474 
475 
476 #define fd_range_sub_value(r, t) \
477  Pl_Range_Add_Value(&R(r), -(t));
478 
479 
480 
481 
482 #define fd_range_mul_value(r, t) \
483  Pl_Range_Mul_Value(&R(r), t);
484 
485 
486 
487 
488 #define fd_range_div_value(r, t) \
489  Pl_Range_Div_Value(&R(r), t);
490 
491 
492 
493 
494 #define fd_range_mod_value(r, t) \
495  Pl_Range_Mod_Value(&R(r), t);
496 
497 
498 
499 
500 #define fd_range_copy(r, r1) \
501  R(r).vec = NULL; \
502  Pl_Range_Copy(&R(r), &R(r1));
503 
504 
505 
506 
507 #define fd_range_fct(fct_name, r, args) \
508 { \
509  void fct_name(); \
510  R(r).vec = NULL; \
511  fct_name(&R(r), args); \
512 }
513 
514 
515 
516  /* term */
517 
518 #define fd_load_int(var_name, fp) \
519  var_name = Frame_Term_Parameter(fp);
520 
521 
522 
523 
524 #define fd_load_min(var_name, fv) \
525  fdv_adr = Frame_Variable(fv); \
526  var_name = Min(fdv_adr);
527 
528 
529 
530 
531 #define fd_load_max(var_name, fv) \
532  fdv_adr = Frame_Variable(fv); \
533  var_name = Max(fdv_adr);
534 
535 
536 
537 
538 #define fd_load_min_max(var_name_min, var_name_max, fv) \
539  fdv_adr = Frame_Variable(fv); \
540  var_name_min = Min(fdv_adr); \
541  var_name_max = Max(fdv_adr);
542 
543 
544 
545 
546 #define fd_load_val(var_name, fv) \
547  fdv_adr = Frame_Variable(fv); \
548  if (Fd_Variable_Is_Ground(fdv_adr)) \
549  var_name = Min(fdv_adr); \
550  else \
551  goto lab_exit;
552 
553 
554 
555 
556 #define fd_min_of_range(var_name, r) \
557  var_name = R(r).min;
558 
559 
560 
561 
562 #define fd_max_of_range(var_name, r) \
563  var_name = R(r).max;
564 
565 
566 
567 
568 #define fd_value_copy(t, t1) \
569  (t) = (t1);
570 
571 
572 
573 
574 #define fd_load_l_int(var_name, fp) \
575  var_name = Frame_List_Parameter(fp);
576 
577 
578 
579 
580 #define fd_load_l_fdv(var_name, fp) \
581  var_name = Frame_List_Parameter(fp);
582 
583 
584 
585 
586 #define fd_load_l_any(var_name, fp) \
587  var_name = Frame_List_Parameter(fp);
588 
589 
590 
591 
592 #define arg_1(a1) a1
593 #define arg_2(a1, a2) a1, a2
594 #define arg_3(a1, a2, a3) a1, a2, a3
595 #define arg_4(a1, a2, a3, a4) a1, a2, a3, a4
596 #define arg_5(a1, a2, a3, a4, a5) a1, a2, a3, a4, a5
597 #define arg_6(a1, a2, a3, a4, a5, a6) a1, a2, a3, a4, a5, a6
598 #define arg_7(a1, a2, a3, a4, a5, a6, a7) a1, a2, a3, a4, a5, a6, a7
599 #define arg_8(a1, a2, a3, a4, a5, a6, a7, a8) a1, a2, a3, a4, a5, a6, a7, a8
600 #define arg_9(a1, a2, a3, a4, a5, a6, a7, a8, a9) a1, a2, a3, a4, a5, a6, a7, a8, a9
601 
602 
603 
604 
605 #define range_arg(r) &R(r) /* by address */
606 
607 
608 
609 
610 /*---------------------------------*
611  * Interface with C files *
612  *---------------------------------*/
613 
614 #define max_integer INTERVAL_MAX_INTEGER
615 
616 
617 
618 
619 #define FdArg(arg) WamWord fd_##arg
620 
621 
622 
623 
624 #define fd_begin_user_constraint(name_args) \
625 Bool \
626 name_args \
627 { \
628  WamWord *AF; \
629  PlLong ret_val = TRUE;
630 
631 
632 
633 
634 #define fd_end_user_constraint \
635 }
636 
637 
638 
639 
640 #define fd_begin_internal(fct_name) \
641 static PlLong \
642 fct_name(WamWord *AF) \
643 { \
644  PlLong ret_val = TRUE;
645 
646 
647 
648 
649 #define fd_end_internal \
650 }
651 
652 
653 
654 
655 #define fd_exit_point \
656  lab_exit:
657 
658 
659 
660 #define fd_return \
661  return ret_val;
662 
663 
664 
665 
666 #define fd_local_value_var(var_name) \
667  int var_name;
668 
669 
670 
671 
672 #define fd_local_range_var(r) \
673  Range R(r); /* = {FALSE, 0, 0, NULL} init should be useless */
674 
675 
676 
677 
678 #define fd_local_l_int_var(var_name) \
679  WamWord *var_name;
680 
681 
682 
683 
684 #define fd_local_l_fdv_var(var_name) \
685  WamWord *var_name;
686 
687 
688 
689 
690 #define fd_local_l_any_var(var_name) \
691  WamWord *var_name;
692 
693 
694 
695 
696 #define fd_local_cf_pointer \
697  WamWord *CF;
698 
699 
700 #ifdef __GNUC__
701 #define fd_local_fdv_adr \
702  WamWord *fdv_adr __attribute__((unused));
703 #else
704 #define fd_local_fdv_adr \
705  WamWord *fdv_adr;
706 #endif
707 
708 
709 
710 #define fd_init_local_value_var(var_name, term) \
711  var_name = (term);
712 
713 
714 
715 
716 #define fd_forall(fv, l_fv) \
717 { \
718  int n = *l_fv++; \
719  while (n--) \
720  { \
721  AF[fv] = *l_fv++;
722 
723 
724 
725 
726 #define fd_forall_end \
727  } \
728 }
729 
730 
731 #endif /* !_FD_TO_C_H */