| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | /************************************************************************
 | 
					
						
							|  |  |  | **                                                                     ** | 
					
						
							|  |  |  | **                   The YapTab/YapOr/OPTYap systems                   ** | 
					
						
							|  |  |  | **                                                                     ** | 
					
						
							|  |  |  | ** YapTab extends the Yap Prolog engine to support sequential tabling  ** | 
					
						
							|  |  |  | ** YapOr extends the Yap Prolog engine to support or-parallelism       ** | 
					
						
							|  |  |  | ** OPTYap extends the Yap Prolog engine to support or-parallel tabling ** | 
					
						
							|  |  |  | **                                                                     ** | 
					
						
							|  |  |  | **                                                                     ** | 
					
						
							|  |  |  | **      Yap Prolog was developed at University of Porto, Portugal      ** | 
					
						
							|  |  |  | **                                                                     ** | 
					
						
							|  |  |  | ************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /************************************
 | 
					
						
							|  |  |  | **      Includes & Prototypes      ** | 
					
						
							|  |  |  | ************************************/ | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "Yap.h"
 | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  | #include "Yatom.h"
 | 
					
						
							| 
									
										
										
										
											2009-10-23 14:22:17 +01:00
										 |  |  | #include "YapHeap.h"
 | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  | #include "eval.h"
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #include "tab.macros.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static inline sg_node_ptr | 
					
						
							|  |  |  | subgoal_trie_check_insert_entry(tab_ent_ptr, sg_node_ptr, Term USES_REGS); | 
					
						
							|  |  |  | static inline sg_node_ptr | 
					
						
							|  |  |  | subgoal_trie_check_insert_gt_entry(tab_ent_ptr, sg_node_ptr, Term USES_REGS); | 
					
						
							|  |  |  | static inline ans_node_ptr | 
					
						
							|  |  |  | answer_trie_check_insert_entry(sg_fr_ptr, ans_node_ptr, Term, int USES_REGS); | 
					
						
							|  |  |  | static inline ans_node_ptr | 
					
						
							|  |  |  | answer_trie_check_insert_gt_entry(sg_fr_ptr, ans_node_ptr, Term, int USES_REGS); | 
					
						
							|  |  |  | static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr, | 
					
						
							|  |  |  |                                                          Term USES_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #ifdef GLOBAL_TRIE_FOR_SUBTERMS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static inline gt_node_ptr global_trie_check_insert_gt_entry(gt_node_ptr, | 
					
						
							|  |  |  |                                                             Term USES_REGS); | 
					
						
							|  |  |  | #endif /* GLOBAL_TRIE_FOR_SUBTERMS */
 | 
					
						
							|  |  |  | static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr, sg_node_ptr, Term, | 
					
						
							|  |  |  |                                               int *, CELL **USES_REGS); | 
					
						
							|  |  |  | static inline sg_node_ptr subgoal_search_terms_loop(tab_ent_ptr, sg_node_ptr, | 
					
						
							|  |  |  |                                                     Term, int *, | 
					
						
							|  |  |  |                                                     CELL **USES_REGS); | 
					
						
							|  |  |  | static inline ans_node_ptr answer_search_loop(sg_fr_ptr, ans_node_ptr, Term, | 
					
						
							|  |  |  |                                               int *USES_REGS); | 
					
						
							|  |  |  | static inline ans_node_ptr answer_search_terms_loop(sg_fr_ptr, ans_node_ptr, | 
					
						
							|  |  |  |                                                     Term, int *USES_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #ifdef GLOBAL_TRIE_FOR_SUBTERMS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static inline gt_node_ptr | 
					
						
							|  |  |  | subgoal_search_global_trie_terms_loop(Term, int *, CELL **, CELL *USES_REGS); | 
					
						
							|  |  |  | static inline gt_node_ptr answer_search_global_trie_terms_loop(Term, int *, | 
					
						
							|  |  |  |                                                                CELL *USES_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static inline gt_node_ptr subgoal_search_global_trie_loop(Term, int *, | 
					
						
							|  |  |  |                                                           CELL **USES_REGS); | 
					
						
							|  |  |  | static inline gt_node_ptr answer_search_global_trie_loop(Term, int *USES_REGS); | 
					
						
							|  |  |  | #endif /* GLOBAL_TRIE_MODE */
 | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  | static inline CELL *load_answer_loop(ans_node_ptr USES_REGS); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static inline CELL *load_substitution_loop(gt_node_ptr, int *, CELL *USES_REGS); | 
					
						
							|  |  |  | static inline CELL *exec_substitution_loop(gt_node_ptr, CELL **, | 
					
						
							|  |  |  |                                            CELL *USES_REGS); | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  | #ifdef MODE_DIRECTED_TABLING
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static inline ans_node_ptr answer_search_min_max(sg_fr_ptr, ans_node_ptr, Term, | 
					
						
							|  |  |  |                                                  int USES_REGS); | 
					
						
							|  |  |  | static inline ans_node_ptr answer_search_sum(sg_fr_ptr, ans_node_ptr, | 
					
						
							|  |  |  |                                              Term USES_REGS); | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  | static void invalidate_answer_trie(ans_node_ptr, sg_fr_ptr, int USES_REGS); | 
					
						
							|  |  |  | #endif /* MODE_DIRECTED_TABLING */
 | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #ifdef YAPOR
 | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  | static int update_answer_trie_branch(ans_node_ptr, ans_node_ptr); | 
					
						
							|  |  |  | #else /* YAPOR && ! TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  | static int update_answer_trie_branch(ans_node_ptr); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #else /* ! YAPOR */
 | 
					
						
							|  |  |  | static void update_answer_trie_branch(ans_node_ptr, int); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #ifdef GLOBAL_TRIE_FOR_SUBTERMS
 | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  | static void free_global_trie_branch(gt_node_ptr, int USES_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  | static void free_global_trie_branch(gt_node_ptr USES_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #endif /* GLOBAL_TRIE_FOR_SUBTERMS */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static void traverse_subgoal_trie(sg_node_ptr, char *, int, int *, int, | 
					
						
							|  |  |  |                                   int USES_REGS); | 
					
						
							|  |  |  | static void traverse_answer_trie(ans_node_ptr, char *, int, int *, int, int, | 
					
						
							|  |  |  |                                  int USES_REGS); | 
					
						
							|  |  |  | static void traverse_global_trie(gt_node_ptr, char *, int, int *, int, | 
					
						
							|  |  |  |                                  int USES_REGS); | 
					
						
							|  |  |  | static void traverse_global_trie_for_term(gt_node_ptr, char *, int *, int *, | 
					
						
							|  |  |  |                                           int *, int USES_REGS); | 
					
						
							|  |  |  | static inline void traverse_trie_node(Term, char *, int *, int *, int *, | 
					
						
							|  |  |  |                                       int USES_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | static inline void traverse_update_arity(char *, int *, int *); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | /*******************************
 | 
					
						
							|  |  |  | **      Structs & Macros      ** | 
					
						
							|  |  |  | *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static struct trie_statistics { | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |   FILE *out; | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   int show; | 
					
						
							|  |  |  |   long subgoals; | 
					
						
							|  |  |  |   long subgoals_incomplete; | 
					
						
							|  |  |  |   long subgoal_trie_nodes; | 
					
						
							|  |  |  |   long answers; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   long answers_pruned; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   long answers_true; | 
					
						
							|  |  |  |   long answers_no; | 
					
						
							|  |  |  |   long answer_trie_nodes; | 
					
						
							|  |  |  |   long global_trie_terms; | 
					
						
							|  |  |  |   long global_trie_nodes; | 
					
						
							| 
									
										
										
										
											2010-04-16 03:07:37 +01:00
										 |  |  |   long global_trie_references; | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | #ifdef THREADS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | trie_stats[MAX_THREADS]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define TrStat_out trie_stats[worker_id].out
 | 
					
						
							|  |  |  | #define TrStat_show trie_stats[worker_id].show
 | 
					
						
							|  |  |  | #define TrStat_subgoals trie_stats[worker_id].subgoals
 | 
					
						
							|  |  |  | #define TrStat_sg_incomplete trie_stats[worker_id].subgoals_incomplete
 | 
					
						
							|  |  |  | #define TrStat_sg_nodes trie_stats[worker_id].subgoal_trie_nodes
 | 
					
						
							|  |  |  | #define TrStat_answers trie_stats[worker_id].answers
 | 
					
						
							|  |  |  | #define TrStat_answers_true trie_stats[worker_id].answers_true
 | 
					
						
							|  |  |  | #define TrStat_answers_no trie_stats[worker_id].answers_no
 | 
					
						
							|  |  |  | #define TrStat_answers_pruned trie_stats[worker_id].answers_pruned
 | 
					
						
							|  |  |  | #define TrStat_ans_nodes trie_stats[worker_id].answer_trie_nodes
 | 
					
						
							|  |  |  | #define TrStat_gt_terms trie_stats[worker_id].global_trie_terms
 | 
					
						
							|  |  |  | #define TrStat_gt_nodes trie_stats[worker_id].global_trie_nodes
 | 
					
						
							|  |  |  | #define TrStat_gt_refs trie_stats[worker_id].global_trie_references
 | 
					
						
							|  |  |  | #else /*!THREADS */
 | 
					
						
							|  |  |  | trie_stats; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define TrStat_out trie_stats.out
 | 
					
						
							|  |  |  | #define TrStat_show trie_stats.show
 | 
					
						
							|  |  |  | #define TrStat_subgoals trie_stats.subgoals
 | 
					
						
							|  |  |  | #define TrStat_sg_incomplete trie_stats.subgoals_incomplete
 | 
					
						
							|  |  |  | #define TrStat_sg_nodes trie_stats.subgoal_trie_nodes
 | 
					
						
							|  |  |  | #define TrStat_answers trie_stats.answers
 | 
					
						
							|  |  |  | #define TrStat_answers_true trie_stats.answers_true
 | 
					
						
							|  |  |  | #define TrStat_answers_no trie_stats.answers_no
 | 
					
						
							|  |  |  | #define TrStat_answers_pruned trie_stats.answers_pruned
 | 
					
						
							|  |  |  | #define TrStat_ans_nodes trie_stats.answer_trie_nodes
 | 
					
						
							|  |  |  | #define TrStat_gt_terms trie_stats.global_trie_terms
 | 
					
						
							|  |  |  | #define TrStat_gt_nodes trie_stats.global_trie_nodes
 | 
					
						
							|  |  |  | #define TrStat_gt_refs trie_stats.global_trie_references
 | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #endif /*THREADS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #if defined(THREADS_SUBGOAL_SHARING) || defined(THREADS_FULL_SHARING) ||       \
 | 
					
						
							|  |  |  |     defined(THREADS_CONSUMER_SHARING) | 
					
						
							|  |  |  | #define IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES                         \
 | 
					
						
							|  |  |  |   if (GLOBAL_NOfThreads == 1) | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #define IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #endif /* THREADS_SUBGOAL_SHARING || THREADS_FULL_SHARING ||                   \
 | 
					
						
							|  |  |  |           THREADS_CONSUMER_SHARING */ | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES                          \
 | 
					
						
							|  |  |  |   if (GLOBAL_NOfThreads == 1) | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #define IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES
 | 
					
						
							|  |  |  | #endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define SHOW_TABLE_STR_ARRAY_SIZE 100000
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #define SHOW_TABLE_ARITY_ARRAY_SIZE 10000
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define SHOW_TABLE_STRUCTURE(MESG, ARGS...)                                    \
 | 
					
						
							|  |  |  |   if (TrStat_show == SHOW_MODE_STRUCTURE)                                      \ | 
					
						
							|  |  |  |   fprintf(TrStat_out, MESG, ##ARGS) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(REF, MODE)                       \
 | 
					
						
							|  |  |  |   if (MODE == TRAVERSE_MODE_NORMAL && IsVarTerm(REF) &&                        \ | 
					
						
							|  |  |  |       REF > VarIndexOfTableTerm(MAX_TABLE_VARS)) {                             \ | 
					
						
							|  |  |  |     register gt_node_ptr gt_node = (gt_node_ptr)(REF);                         \ | 
					
						
							|  |  |  |     TrNode_child(gt_node) =                                                    \ | 
					
						
							|  |  |  |         (gt_node_ptr)((uintptr_t)TrNode_child(gt_node) - 1);                   \ | 
					
						
							|  |  |  |     if (TrNode_child(gt_node) == 0)                                            \ | 
					
						
							|  |  |  |       FREE_GLOBAL_TRIE_BRANCH(gt_node, TRAVERSE_MODE_NORMAL);                  \ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  | #ifdef GLOBAL_TRIE_FOR_SUBTERMS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(REF, MODE)          \
 | 
					
						
							|  |  |  |   CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(REF, MODE) | 
					
						
							|  |  |  | #define FREE_GLOBAL_TRIE_BRANCH(NODE, MODE)                                    \
 | 
					
						
							|  |  |  |   free_global_trie_branch(NODE, MODE PASS_REGS) | 
					
						
							| 
									
										
										
										
											2009-08-07 06:27:34 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(REF, MODE)
 | 
					
						
							|  |  |  | #define FREE_GLOBAL_TRIE_BRANCH(NODE, MODE)                                    \
 | 
					
						
							|  |  |  |   free_global_trie_branch(NODE PASS_REGS) | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #endif /* GLOBAL_TRIE_FOR_SUBTERMS */
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  | /******************************
 | 
					
						
							|  |  |  | ** Rational Terms Support    ** | 
					
						
							|  |  |  | ******************************/ | 
					
						
							|  |  |  | #ifdef TRIE_RATIONAL_TERMS
 | 
					
						
							| 
									
										
										
										
											2015-01-20 03:00:42 +00:00
										 |  |  | #include "tab.rational.h"
 | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  | #endif /* RATIONAL TERM SUPPORT FOR TRIES */
 | 
					
						
							| 
									
										
										
										
											2002-05-03 15:30:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | /******************************
 | 
					
						
							|  |  |  | **      Local functions      ** | 
					
						
							|  |  |  | ******************************/ | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define INCLUDE_SUBGOAL_TRIE_CHECK_INSERT /* subgoal_trie_check_insert_entry   \
 | 
					
						
							|  |  |  |                                              */ | 
					
						
							|  |  |  | #define INCLUDE_ANSWER_TRIE_CHECK_INSERT  /* answer_trie_check_insert_entry */
 | 
					
						
							|  |  |  | #define INCLUDE_GLOBAL_TRIE_CHECK_INSERT  /* global_trie_check_insert_entry */
 | 
					
						
							| 
									
										
										
										
											2015-01-20 03:00:42 +00:00
										 |  |  | #include "tab.tries.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  | #undef INCLUDE_GLOBAL_TRIE_CHECK_INSERT
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #undef INCLUDE_ANSWER_TRIE_CHECK_INSERT
 | 
					
						
							|  |  |  | #undef INCLUDE_SUBGOAL_TRIE_CHECK_INSERT
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-15 01:09:59 +01:00
										 |  |  | #define MODE_GLOBAL_TRIE_ENTRY
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define INCLUDE_SUBGOAL_TRIE_CHECK_INSERT /* subgoal_trie_check_insert_gt_entry \
 | 
					
						
							|  |  |  |                                              */ | 
					
						
							|  |  |  | #define INCLUDE_ANSWER_TRIE_CHECK_INSERT  /* answer_trie_check_insert_gt_entry \
 | 
					
						
							|  |  |  |                                              */ | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  | #ifdef GLOBAL_TRIE_FOR_SUBTERMS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define INCLUDE_GLOBAL_TRIE_CHECK_INSERT /* global_trie_check_insert_gt_entry  \
 | 
					
						
							|  |  |  |                                             */ | 
					
						
							|  |  |  | #endif                                   /* GLOBAL_TRIE_FOR_SUBTERMS */
 | 
					
						
							| 
									
										
										
										
											2015-01-20 03:00:42 +00:00
										 |  |  | #include "tab.tries.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-15 01:09:59 +01:00
										 |  |  | #undef INCLUDE_GLOBAL_TRIE_CHECK_INSERT
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #undef INCLUDE_ANSWER_TRIE_CHECK_INSERT
 | 
					
						
							|  |  |  | #undef INCLUDE_SUBGOAL_TRIE_CHECK_INSERT
 | 
					
						
							|  |  |  | #undef MODE_GLOBAL_TRIE_ENTRY
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_loop */
 | 
					
						
							|  |  |  | #define INCLUDE_ANSWER_SEARCH_LOOP  /* answer_search_loop */
 | 
					
						
							|  |  |  | #define INCLUDE_LOAD_ANSWER_LOOP    /* load_answer_loop */
 | 
					
						
							| 
									
										
										
										
											2015-01-20 03:00:42 +00:00
										 |  |  | #include "tab.tries.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #undef INCLUDE_LOAD_ANSWER_LOOP
 | 
					
						
							|  |  |  | #undef INCLUDE_ANSWER_SEARCH_LOOP
 | 
					
						
							| 
									
										
										
										
											2010-04-15 01:09:59 +01:00
										 |  |  | #undef INCLUDE_SUBGOAL_SEARCH_LOOP
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define MODE_TERMS_LOOP
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_terms_loop */
 | 
					
						
							|  |  |  | #define INCLUDE_ANSWER_SEARCH_LOOP  /* answer_search_terms_loop */
 | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  | #ifdef TRIE_RATIONAL_TERMS
 | 
					
						
							|  |  |  | #undef TRIE_RATIONAL_TERMS
 | 
					
						
							| 
									
										
										
										
											2015-01-20 03:00:42 +00:00
										 |  |  | #include "tab.tries.h"
 | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  | #define TRIE_RATIONAL_TERMS
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-01-20 03:00:42 +00:00
										 |  |  | #include "tab.tries.h"
 | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-04-15 01:09:59 +01:00
										 |  |  | #undef INCLUDE_ANSWER_SEARCH_LOOP
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #undef INCLUDE_SUBGOAL_SEARCH_LOOP
 | 
					
						
							|  |  |  | #undef MODE_TERMS_LOOP
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MODE_GLOBAL_TRIE_LOOP
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_global_trie_(terms)_loop \
 | 
					
						
							|  |  |  |                                        */ | 
					
						
							|  |  |  | #define INCLUDE_ANSWER_SEARCH_LOOP  /* answer_search_global_trie_(terms)_loop  \
 | 
					
						
							|  |  |  |                                        */ | 
					
						
							|  |  |  | #define INCLUDE_LOAD_ANSWER_LOOP    /* load_substitution_loop */
 | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  | #ifdef TRIE_RATIONAL_TERMS
 | 
					
						
							|  |  |  | #undef TRIE_RATIONAL_TERMS
 | 
					
						
							| 
									
										
										
										
											2015-01-20 03:00:42 +00:00
										 |  |  | #include "tab.tries.h"
 | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  | #define TRIE_RATIONAL_TERMS
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-01-20 03:00:42 +00:00
										 |  |  | #include "tab.tries.h"
 | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-04-15 01:09:59 +01:00
										 |  |  | #undef INCLUDE_LOAD_ANSWER_LOOP
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #undef INCLUDE_ANSWER_SEARCH_LOOP
 | 
					
						
							|  |  |  | #undef INCLUDE_SUBGOAL_SEARCH_LOOP
 | 
					
						
							|  |  |  | #undef MODE_GLOBAL_TRIE_LOOP
 | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  | #ifdef MODE_DIRECTED_TABLING
 | 
					
						
							|  |  |  | #define INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #include "tab.tries.h" /* answer_search_min_max + answer_search_sum + invalidate_answer_trie */
 | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  | #undef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED
 | 
					
						
							|  |  |  | #endif /* MODE_DIRECTED_TABLING */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static inline CELL *exec_substitution_loop(gt_node_ptr current_node, | 
					
						
							|  |  |  |                                            CELL **stack_vars_ptr, | 
					
						
							|  |  |  |                                            CELL *stack_terms USES_REGS) { | 
					
						
							|  |  |  |   /************************************************************************
 | 
					
						
							|  |  |  |                        =========== | 
					
						
							|  |  |  |                        |         | | 
					
						
							|  |  |  |                        |   ...   | | 
					
						
							|  |  |  |                        |         | | 
					
						
							|  |  |  |                        ----------- | 
					
						
							|  |  |  |              YENV -->  |   N+1   |  <-- stack_vars | 
					
						
							|  |  |  |                        ----------- | 
					
						
							|  |  |  |                        |  VAR_N  | | 
					
						
							|  |  |  |                        ----------- | 
					
						
							|  |  |  |                        |   ...   | | 
					
						
							|  |  |  |                        ----------- | 
					
						
							|  |  |  |                        |  VAR_0  | | 
					
						
							|  |  |  |                        ----------- | 
					
						
							|  |  |  |                        |         | | 
					
						
							|  |  |  |                        |   ...   | | 
					
						
							|  |  |  |                        |         | | 
					
						
							|  |  |  |                        =========== | 
					
						
							|  |  |  |                        |         | | 
					
						
							|  |  |  |                        |   ...   | | 
					
						
							|  |  |  |                        |         | | 
					
						
							|  |  |  |                        ----------- | 
					
						
							|  |  |  |                TR -->  |         |  <-- stack_terms_limit | 
					
						
							|  |  |  |                        ----------- | 
					
						
							|  |  |  |                        |         | | 
					
						
							|  |  |  |                        |   ...   | | 
					
						
							|  |  |  |                        |         | | 
					
						
							|  |  |  |                        ----------| | 
					
						
							|  |  |  |                        |  TERM_N |  <-- stack_terms | 
					
						
							|  |  |  |                        ----------|           * | 
					
						
							|  |  |  |                        |   ...   |          /|\ | 
					
						
							|  |  |  |                        ----------|           |  stack_terms_pair_offset | 
					
						
							|  |  |  |   (TRIE_COMPACT_PAIRS) | 
					
						
							|  |  |  |                        |  TERM_1 |          \|/ | 
					
						
							|  |  |  |                        ===========           * | 
					
						
							|  |  |  |    LOCAL_TrailTop -->  |         |  <-- stack_terms_base (TRIE_COMPACT_PAIRS) | 
					
						
							|  |  |  |                        ----------- | 
					
						
							|  |  |  |   ************************************************************************/ | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  |   CELL *stack_vars = *stack_vars_ptr; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   CELL *stack_terms_limit = (CELL *)TR; | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  | #ifdef TRIE_COMPACT_PAIRS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #define stack_terms_base ((CELL *)LOCAL_TrailTop)
 | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   int stack_terms_pair_offset = 0; | 
					
						
							|  |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   Term t = TrNode_entry(current_node); | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   current_node = TrNode_parent(current_node); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  |   do { | 
					
						
							|  |  |  |     if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #ifdef GLOBAL_TRIE_FOR_SUBTERMS
 | 
					
						
							|  |  |  |       if (t > VarIndexOfTableTerm(MAX_TABLE_VARS)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         stack_terms = exec_substitution_loop((gt_node_ptr)t, &stack_vars, | 
					
						
							|  |  |  |                                              stack_terms PASS_REGS); | 
					
						
							|  |  |  |       } else | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #endif /* GLOBAL_TRIE_FOR_SUBTERMS */
 | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         int var_index = VarIndexOfTableTerm(t); | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  |         int vars_arity = *stack_vars; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         t = MkVarTerm(); | 
					
						
							|  |  |  |         if (var_index >= vars_arity) { | 
					
						
							|  |  |  |           while (vars_arity < var_index) { | 
					
						
							|  |  |  |             *stack_vars-- = 0; | 
					
						
							|  |  |  |             vars_arity++; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           *stack_vars-- = t; | 
					
						
							|  |  |  |           vars_arity++; | 
					
						
							|  |  |  |           *stack_vars = vars_arity; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           /* do the same as in macro stack_trie_val_instr() */ | 
					
						
							|  |  |  |           CELL aux_sub, aux_var, *vars_ptr; | 
					
						
							|  |  |  |           vars_ptr = stack_vars + vars_arity - var_index; | 
					
						
							|  |  |  |           aux_sub = *((CELL *)t); | 
					
						
							|  |  |  |           aux_var = *vars_ptr; | 
					
						
							|  |  |  |           if (aux_var == 0) { | 
					
						
							|  |  |  |             *vars_ptr = t; | 
					
						
							|  |  |  |           } else { | 
					
						
							|  |  |  |             if (aux_sub > aux_var) { | 
					
						
							|  |  |  |               if ((CELL *)aux_sub <= HR) { | 
					
						
							|  |  |  |                 Bind_Global((CELL *)aux_sub, aux_var); | 
					
						
							|  |  |  |               } else if ((CELL *)aux_var <= HR) { | 
					
						
							|  |  |  |                 Bind_Local((CELL *)aux_sub, aux_var); | 
					
						
							|  |  |  |               } else { | 
					
						
							|  |  |  |                 Bind_Local((CELL *)aux_var, aux_sub); | 
					
						
							|  |  |  |                 *vars_ptr = aux_sub; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |               if ((CELL *)aux_var <= HR) { | 
					
						
							|  |  |  |                 Bind_Global((CELL *)aux_var, aux_sub); | 
					
						
							|  |  |  |                 *vars_ptr = aux_sub; | 
					
						
							|  |  |  |               } else if ((CELL *)aux_sub <= HR) { | 
					
						
							|  |  |  |                 Bind_Local((CELL *)aux_var, aux_sub); | 
					
						
							|  |  |  |                 *vars_ptr = aux_sub; | 
					
						
							|  |  |  |               } else { | 
					
						
							|  |  |  |                 Bind_Local((CELL *)aux_sub, aux_var); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit); | 
					
						
							|  |  |  |         STACK_PUSH_UP(t, stack_terms); | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  |     } else if (IsAtomOrIntTerm(t)) { | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |       AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit); | 
					
						
							| 
									
										
										
										
											2009-06-17 17:14:16 +01:00
										 |  |  |       STACK_PUSH_UP(t, stack_terms); | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  |     } else if (IsPairTerm(t)) { | 
					
						
							| 
									
										
										
										
											2009-07-05 05:14:08 +01:00
										 |  |  | #ifdef TRIE_COMPACT_PAIRS
 | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |       if (t == CompactPairInit) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         Term *stack_aux = stack_terms_base - stack_terms_pair_offset; | 
					
						
							|  |  |  |         Term head, tail = STACK_POP_UP(stack_aux); | 
					
						
							|  |  |  |         while (STACK_NOT_EMPTY(stack_aux, stack_terms)) { | 
					
						
							|  |  |  |           head = STACK_POP_UP(stack_aux); | 
					
						
							|  |  |  |           tail = MkPairTerm(head, tail); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         stack_terms = stack_terms_base - stack_terms_pair_offset; | 
					
						
							|  |  |  |         stack_terms_pair_offset = (int)STACK_POP_DOWN(stack_terms); | 
					
						
							|  |  |  |         STACK_PUSH_UP(tail, stack_terms); | 
					
						
							|  |  |  |       } else { /* CompactPairEndList / CompactPairEndTerm */ | 
					
						
							|  |  |  |         Term last; | 
					
						
							|  |  |  |         AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit + 1); | 
					
						
							|  |  |  |         last = STACK_POP_DOWN(stack_terms); | 
					
						
							|  |  |  |         STACK_PUSH_UP(stack_terms_pair_offset, stack_terms); | 
					
						
							|  |  |  |         stack_terms_pair_offset = (int)(stack_terms_base - stack_terms); | 
					
						
							|  |  |  |         if (t == CompactPairEndList) | 
					
						
							|  |  |  |           STACK_PUSH_UP(TermNil, stack_terms); | 
					
						
							|  |  |  |         STACK_PUSH_UP(last, stack_terms); | 
					
						
							| 
									
										
										
										
											2009-06-24 20:04:16 +01:00
										 |  |  |       } | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  |       Term head = STACK_POP_DOWN(stack_terms); | 
					
						
							|  |  |  |       Term tail = STACK_POP_DOWN(stack_terms); | 
					
						
							|  |  |  |       t = MkPairTerm(head, tail); | 
					
						
							|  |  |  |       STACK_PUSH_UP(t, stack_terms); | 
					
						
							| 
									
										
										
										
											2009-07-05 05:14:08 +01:00
										 |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  |     } else if (IsApplTerm(t)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       Functor f = (Functor)RepAppl(t); | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  |       if (f == FunctorDouble) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         union { | 
					
						
							|  |  |  |           Term t_dbl[sizeof(Float) / sizeof(Term)]; | 
					
						
							|  |  |  |           Float dbl; | 
					
						
							|  |  |  |         } u; | 
					
						
							|  |  |  |         t = TrNode_entry(current_node); | 
					
						
							|  |  |  |         current_node = TrNode_parent(current_node); | 
					
						
							|  |  |  |         u.t_dbl[0] = t; | 
					
						
							| 
									
										
										
										
											2007-04-26 14:13:21 +00:00
										 |  |  | #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         t = TrNode_entry(current_node); | 
					
						
							|  |  |  |         current_node = TrNode_parent(current_node); | 
					
						
							|  |  |  |         u.t_dbl[1] = t; | 
					
						
							| 
									
										
										
										
											2007-04-26 14:13:21 +00:00
										 |  |  | #endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         current_node = TrNode_parent(current_node); | 
					
						
							|  |  |  |         t = MkFloatTerm(u.dbl); | 
					
						
							| 
									
										
										
										
											2005-06-04 07:28:24 +00:00
										 |  |  |       } else if (f == FunctorLongInt) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         Int li = TrNode_entry(current_node); | 
					
						
							|  |  |  |         current_node = TrNode_parent(current_node); | 
					
						
							|  |  |  |         current_node = TrNode_parent(current_node); | 
					
						
							|  |  |  |         t = MkLongIntTerm(li); | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         int f_arity = ArityOfFunctor(f); | 
					
						
							|  |  |  |         t = Yap_MkApplTerm(f, f_arity, stack_terms); | 
					
						
							|  |  |  |         stack_terms += f_arity; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-04-03 16:05:38 +01:00
										 |  |  |       AUX_STACK_CHECK_EXPAND(stack_terms, stack_terms_limit); | 
					
						
							|  |  |  |       STACK_PUSH_UP(t, stack_terms); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |     t = TrNode_entry(current_node); | 
					
						
							|  |  |  |     current_node = TrNode_parent(current_node); | 
					
						
							|  |  |  |   } while (current_node); | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  |   *stack_vars_ptr = stack_vars; | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   return stack_terms; | 
					
						
							| 
									
										
										
										
											2010-04-03 16:05:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #ifdef TRIE_COMPACT_PAIRS
 | 
					
						
							|  |  |  | #undef stack_terms_base
 | 
					
						
							|  |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #ifdef YAPOR
 | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static int update_answer_trie_branch(ans_node_ptr previous_node, | 
					
						
							|  |  |  |                                      ans_node_ptr current_node) { | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   int ltt; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   if (!IS_ANSWER_LEAF_NODE(current_node)) { | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     if (TrNode_child(current_node)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       TrNode_instr(TrNode_child(current_node)) -= 1; /* retry --> try */ | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |       update_answer_trie_branch(NULL, TrNode_child(current_node)); | 
					
						
							|  |  |  |       if (TrNode_child(current_node)) | 
					
						
							|  |  |  |         goto update_next_trie_branch; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     /* node belonging to a pruned answer */ | 
					
						
							|  |  |  |     if (previous_node) { | 
					
						
							|  |  |  |       TrNode_next(previous_node) = TrNode_next(current_node); | 
					
						
							|  |  |  |       FREE_ANSWER_TRIE_NODE(current_node); | 
					
						
							|  |  |  |       if (TrNode_next(previous_node)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         return update_answer_trie_branch(previous_node, | 
					
						
							|  |  |  |                                          TrNode_next(previous_node)); | 
					
						
							| 
									
										
										
										
											2007-04-26 19:02:46 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         TrNode_instr(previous_node) -= 2; /* retry --> trust : try --> do */ | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2007-04-26 19:02:46 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |       TrNode_child(TrNode_parent(current_node)) = TrNode_next(current_node); | 
					
						
							|  |  |  |       if (TrNode_next(current_node)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         TrNode_instr(TrNode_next(current_node)) -= 1; /* retry --> try */ | 
					
						
							|  |  |  |         update_answer_trie_branch(NULL, TrNode_next(current_node)); | 
					
						
							| 
									
										
										
										
											2007-04-26 19:02:46 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |       FREE_ANSWER_TRIE_NODE(current_node); | 
					
						
							|  |  |  |       return 0; | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | update_next_trie_branch: | 
					
						
							|  |  |  |   if (TrNode_next(current_node)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     ltt = | 
					
						
							|  |  |  |         1 + update_answer_trie_branch(current_node, TrNode_next(current_node)); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     TrNode_instr(current_node) -= 2; /* retry --> trust : try --> do */ | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     ltt = 1; | 
					
						
							| 
									
										
										
										
											2009-08-05 05:48:00 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   TrNode_or_arg(current_node) = ltt; | 
					
						
							|  |  |  |   TrNode_instr(current_node) = Yap_opcode(TrNode_instr(current_node)); | 
					
						
							|  |  |  |   return ltt; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #else /* YAPOR && ! TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  | static int update_answer_trie_branch(ans_node_ptr current_node) { | 
					
						
							|  |  |  |   int ltt; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   if (!IS_ANSWER_LEAF_NODE(current_node)) { | 
					
						
							|  |  |  |     TrNode_instr(TrNode_child(current_node)) -= 1; /* retry --> try */ | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     update_answer_trie_branch(TrNode_child(current_node)); | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   if (TrNode_next(current_node)) { | 
					
						
							|  |  |  |     ltt = 1 + update_answer_trie_branch(TrNode_next(current_node)); | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     TrNode_instr(current_node) -= 2; /* retry --> trust : try --> do */ | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     ltt = 1; | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   TrNode_or_arg(current_node) = ltt; | 
					
						
							|  |  |  |   TrNode_instr(current_node) = Yap_opcode(TrNode_instr(current_node)); | 
					
						
							|  |  |  |   return ltt; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #else /* ! YAPOR */
 | 
					
						
							|  |  |  | static void update_answer_trie_branch(ans_node_ptr current_node, int position) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   if (!IS_ANSWER_LEAF_NODE(current_node)) | 
					
						
							|  |  |  |     update_answer_trie_branch(TrNode_child(current_node), | 
					
						
							|  |  |  |                               TRAVERSE_POSITION_FIRST); /* retry --> try */ | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   if (position == TRAVERSE_POSITION_FIRST) { | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     ans_node_ptr next = TrNode_next(current_node); | 
					
						
							|  |  |  |     if (next) { | 
					
						
							|  |  |  |       while (TrNode_next(next)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         update_answer_trie_branch(next, | 
					
						
							|  |  |  |                                   TRAVERSE_POSITION_NEXT); /* retry --> retry */ | 
					
						
							|  |  |  |         next = TrNode_next(next); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       update_answer_trie_branch(next, | 
					
						
							|  |  |  |                                 TRAVERSE_POSITION_LAST); /* retry --> trust */ | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     } else | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       position += TRAVERSE_POSITION_LAST; /* try --> do */ | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   TrNode_instr(current_node) = | 
					
						
							|  |  |  |       Yap_opcode(TrNode_instr(current_node) - position); | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #endif /* YAPOR */
 | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #ifdef GLOBAL_TRIE_FOR_SUBTERMS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static void free_global_trie_branch(gt_node_ptr current_node, | 
					
						
							|  |  |  |                                     int mode USES_REGS) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   Term t = TrNode_entry(current_node); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  | static void free_global_trie_branch(gt_node_ptr current_node USES_REGS) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #endif /* GLOBAL_TRIE_FOR_SUBTERMS */
 | 
					
						
							|  |  |  |   gt_node_ptr parent_node, child_node; | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   parent_node = TrNode_parent(current_node); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   child_node = TrNode_child(parent_node); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   if (IS_GLOBAL_TRIE_HASH(child_node)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     gt_hash_ptr hash = (gt_hash_ptr)child_node; | 
					
						
							|  |  |  |     gt_node_ptr *bucket = | 
					
						
							|  |  |  |         Hash_buckets(hash) + | 
					
						
							|  |  |  |         HASH_ENTRY(TrNode_entry(current_node), Hash_num_buckets(hash)); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     int num_nodes = --Hash_num_nodes(hash); | 
					
						
							|  |  |  |     child_node = *bucket; | 
					
						
							|  |  |  |     if (child_node != current_node) { | 
					
						
							|  |  |  |       while (TrNode_next(child_node) != current_node) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         child_node = TrNode_next(child_node); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       TrNode_next(child_node) = TrNode_next(current_node); | 
					
						
							|  |  |  |       CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode); | 
					
						
							|  |  |  |       FREE_GLOBAL_TRIE_NODE(current_node); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       *bucket = TrNode_next(current_node); | 
					
						
							|  |  |  |       CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode); | 
					
						
							|  |  |  |       FREE_GLOBAL_TRIE_NODE(current_node); | 
					
						
							|  |  |  |       if (num_nodes == 0) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         FREE_BUCKETS(Hash_buckets(hash)); | 
					
						
							|  |  |  |         FREE_GLOBAL_TRIE_HASH(hash); | 
					
						
							|  |  |  |         if (parent_node != GLOBAL_root_gt) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #ifdef GLOBAL_TRIE_FOR_SUBTERMS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |           if (mode == TRAVERSE_MODE_NORMAL) { | 
					
						
							|  |  |  |             if (IsApplTerm(t)) { | 
					
						
							|  |  |  |               Functor f = (Functor)RepAppl(t); | 
					
						
							|  |  |  |               if (f == FunctorDouble) | 
					
						
							|  |  |  |                 mode = TRAVERSE_MODE_DOUBLE; | 
					
						
							|  |  |  |               else if (f == FunctorLongInt) | 
					
						
							|  |  |  |                 mode = TRAVERSE_MODE_LONGINT; | 
					
						
							|  |  |  |               else if (f == FunctorBigInt || f == FunctorString) | 
					
						
							|  |  |  |                 mode = TRAVERSE_MODE_BIGINT_OR_STRING; | 
					
						
							|  |  |  |               else | 
					
						
							|  |  |  |                 mode = TRAVERSE_MODE_NORMAL; | 
					
						
							|  |  |  |             } else | 
					
						
							|  |  |  |               mode = TRAVERSE_MODE_NORMAL; | 
					
						
							|  |  |  |           } else if (mode == TRAVERSE_MODE_LONGINT) | 
					
						
							|  |  |  |             mode = TRAVERSE_MODE_LONGINT_END; | 
					
						
							|  |  |  |         } else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING) | 
					
						
							|  |  |  |           mode = TRAVERSE_MODE_BIGINT_OR_STRING_END; | 
					
						
							|  |  |  |         else if (mode == TRAVERSE_MODE_DOUBLE) | 
					
						
							| 
									
										
										
										
											2007-04-26 14:13:21 +00:00
										 |  |  | #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |           mode = TRAVERSE_MODE_DOUBLE2; | 
					
						
							|  |  |  |         else if (mode == TRAVERSE_MODE_DOUBLE2) | 
					
						
							| 
									
										
										
										
											2007-04-26 14:13:21 +00:00
										 |  |  | #endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |           mode = TRAVERSE_MODE_DOUBLE_END; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #endif /* GLOBAL_TRIE_FOR_SUBTERMS */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         FREE_GLOBAL_TRIE_BRANCH(parent_node, mode); | 
					
						
							|  |  |  |       } else | 
					
						
							|  |  |  |         TrNode_child(parent_node) = NULL; | 
					
						
							| 
									
										
										
										
											2005-05-31 08:19:31 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | else if (child_node != current_node) { | 
					
						
							|  |  |  |   while (TrNode_next(child_node) != current_node) | 
					
						
							|  |  |  |     child_node = TrNode_next(child_node); | 
					
						
							|  |  |  |   TrNode_next(child_node) = TrNode_next(current_node); | 
					
						
							|  |  |  |   CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode); | 
					
						
							|  |  |  |   FREE_GLOBAL_TRIE_NODE(current_node); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | else if (TrNode_next(current_node) == NULL) { | 
					
						
							|  |  |  |   CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode); | 
					
						
							|  |  |  |   FREE_GLOBAL_TRIE_NODE(current_node); | 
					
						
							|  |  |  |   if (parent_node != GLOBAL_root_gt) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #ifdef GLOBAL_TRIE_FOR_SUBTERMS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     if (mode == TRAVERSE_MODE_NORMAL) { | 
					
						
							|  |  |  |       if (IsApplTerm(t)) { | 
					
						
							|  |  |  |         Functor f = (Functor)RepAppl(t); | 
					
						
							|  |  |  |         if (f == FunctorDouble) | 
					
						
							|  |  |  |           mode = TRAVERSE_MODE_DOUBLE; | 
					
						
							|  |  |  |         else if (f == FunctorLongInt) | 
					
						
							|  |  |  |           mode = TRAVERSE_MODE_LONGINT; | 
					
						
							|  |  |  |         else if (f == FunctorBigInt || f == FunctorString) | 
					
						
							|  |  |  |           mode = TRAVERSE_MODE_BIGINT_OR_STRING; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           mode = TRAVERSE_MODE_NORMAL; | 
					
						
							|  |  |  |       } else | 
					
						
							|  |  |  |         mode = TRAVERSE_MODE_NORMAL; | 
					
						
							|  |  |  |     } else if (mode == TRAVERSE_MODE_LONGINT) { | 
					
						
							|  |  |  |       mode = TRAVERSE_MODE_LONGINT_END; | 
					
						
							|  |  |  |     } else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING) { | 
					
						
							|  |  |  |       mode = TRAVERSE_MODE_BIGINT_OR_STRING_END; | 
					
						
							|  |  |  |     } else if (mode == TRAVERSE_MODE_DOUBLE) | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       mode = TRAVERSE_MODE_DOUBLE2; | 
					
						
							|  |  |  |     else if (mode == TRAVERSE_MODE_DOUBLE2) | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       mode = TRAVERSE_MODE_DOUBLE_END; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #endif /* GLOBAL_TRIE_FOR_SUBTERMS */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     FREE_GLOBAL_TRIE_BRANCH(parent_node, mode); | 
					
						
							|  |  |  |   } else | 
					
						
							|  |  |  |     TrNode_child(parent_node) = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | else { | 
					
						
							|  |  |  |   TrNode_child(parent_node) = TrNode_next(current_node); | 
					
						
							|  |  |  |   CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode); | 
					
						
							|  |  |  |   FREE_GLOBAL_TRIE_NODE(current_node); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | return; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static void traverse_subgoal_trie(sg_node_ptr current_node, char *str, | 
					
						
							|  |  |  |                                   int str_index, int *arity, int mode, | 
					
						
							|  |  |  |                                   int position USES_REGS) { | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   int *current_arity = NULL, current_str_index = 0, current_mode = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* test if hashing */ | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   if (IS_SUBGOAL_TRIE_HASH(current_node)) { | 
					
						
							|  |  |  |     sg_node_ptr *bucket, *last_bucket; | 
					
						
							|  |  |  |     sg_hash_ptr hash; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     hash = (sg_hash_ptr)current_node; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     bucket = Hash_buckets(hash); | 
					
						
							|  |  |  |     last_bucket = bucket + Hash_num_buckets(hash); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     current_arity = (int *)malloc(sizeof(int) * (arity[0] + 1)); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       if (*bucket) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         traverse_subgoal_trie(*bucket, str, str_index, arity, mode, | 
					
						
							|  |  |  |                               TRAVERSE_POSITION_FIRST PASS_REGS); | 
					
						
							|  |  |  |         memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #ifdef TRIE_COMPACT_PAIRS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         if (arity[arity[0]] == -2 && str[str_index - 1] != '[') | 
					
						
							|  |  |  |           str[str_index - 1] = ','; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         if (arity[arity[0]] == -1) | 
					
						
							|  |  |  |           str[str_index - 1] = '|'; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } while (++bucket != last_bucket); | 
					
						
							|  |  |  |     free(current_arity); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* save current state if first sibling node */ | 
					
						
							|  |  |  |   if (position == TRAVERSE_POSITION_FIRST) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     current_arity = (int *)malloc(sizeof(int) * (arity[0] + 1)); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); | 
					
						
							|  |  |  |     current_str_index = str_index; | 
					
						
							|  |  |  |     current_mode = mode; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* process current trie node */ | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   TrStat_sg_nodes++; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   traverse_trie_node(TrNode_entry(current_node), str, &str_index, arity, &mode, | 
					
						
							|  |  |  |                      TRAVERSE_TYPE_SUBGOAL PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   /* show answers ... */ | 
					
						
							|  |  |  |   if (IS_SUBGOAL_LEAF_NODE(current_node)) { | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     sg_fr_ptr sg_fr = get_subgoal_frame(current_node); | 
					
						
							|  |  |  |     if (sg_fr) { | 
					
						
							|  |  |  |       TrStat_subgoals++; | 
					
						
							|  |  |  |       str[str_index] = 0; | 
					
						
							|  |  |  |       SHOW_TABLE_STRUCTURE("%s.\n", str); | 
					
						
							|  |  |  |       TrStat_ans_nodes++; | 
					
						
							|  |  |  |       if (SgFr_first_answer(sg_fr) == NULL) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         if (SgFr_state(sg_fr) < complete) { | 
					
						
							|  |  |  |           TrStat_sg_incomplete++; | 
					
						
							|  |  |  |           SHOW_TABLE_STRUCTURE("    ---> INCOMPLETE\n"); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           TrStat_answers_no++; | 
					
						
							|  |  |  |           SHOW_TABLE_STRUCTURE("    NO\n"); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |       } else if (SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         TrStat_answers_true++; | 
					
						
							|  |  |  |         SHOW_TABLE_STRUCTURE("    TRUE\n"); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         arity[0] = 0; | 
					
						
							|  |  |  |         traverse_answer_trie(TrNode_child(SgFr_answer_trie(sg_fr)), | 
					
						
							|  |  |  |                              &str[str_index], 0, arity, 0, TRAVERSE_MODE_NORMAL, | 
					
						
							|  |  |  |                              TRAVERSE_POSITION_FIRST PASS_REGS); | 
					
						
							|  |  |  |         if (SgFr_state(sg_fr) < complete) { | 
					
						
							|  |  |  |           TrStat_sg_incomplete++; | 
					
						
							|  |  |  |           SHOW_TABLE_STRUCTURE("    ---> INCOMPLETE\n"); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   } else | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     /* ... or continue with child node */ | 
					
						
							|  |  |  |     traverse_subgoal_trie(TrNode_child(current_node), str, str_index, arity, | 
					
						
							|  |  |  |                           mode, TRAVERSE_POSITION_FIRST PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   /* restore the initial state and continue with sibling nodes */ | 
					
						
							|  |  |  |   if (position == TRAVERSE_POSITION_FIRST) { | 
					
						
							|  |  |  |     str_index = current_str_index; | 
					
						
							|  |  |  |     mode = current_mode; | 
					
						
							|  |  |  |     current_node = TrNode_next(current_node); | 
					
						
							|  |  |  |     while (current_node) { | 
					
						
							|  |  |  |       memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); | 
					
						
							|  |  |  | #ifdef TRIE_COMPACT_PAIRS
 | 
					
						
							|  |  |  |       if (arity[arity[0]] == -2 && str[str_index - 1] != '[') | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str[str_index - 1] = ','; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #else
 | 
					
						
							|  |  |  |       if (arity[arity[0]] == -1) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str[str_index - 1] = '|'; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       traverse_subgoal_trie(current_node, str, str_index, arity, mode, | 
					
						
							|  |  |  |                             TRAVERSE_POSITION_NEXT PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |       current_node = TrNode_next(current_node); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     free(current_arity); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static void traverse_answer_trie(ans_node_ptr current_node, char *str, | 
					
						
							|  |  |  |                                  int str_index, int *arity, int var_index, | 
					
						
							|  |  |  |                                  int mode, int position USES_REGS) { | 
					
						
							|  |  |  |   int *current_arity = NULL, current_str_index = 0, current_var_index = 0, | 
					
						
							|  |  |  |       current_mode = 0; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* test if hashing */ | 
					
						
							|  |  |  |   if (IS_ANSWER_TRIE_HASH(current_node)) { | 
					
						
							|  |  |  |     ans_node_ptr *bucket, *last_bucket; | 
					
						
							|  |  |  |     ans_hash_ptr hash; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     hash = (ans_hash_ptr)current_node; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     bucket = Hash_buckets(hash); | 
					
						
							|  |  |  |     last_bucket = bucket + Hash_num_buckets(hash); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     current_arity = (int *)malloc(sizeof(int) * (arity[0] + 1)); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       if (*bucket) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         traverse_answer_trie(*bucket, str, str_index, arity, var_index, mode, | 
					
						
							|  |  |  |                              TRAVERSE_POSITION_FIRST PASS_REGS); | 
					
						
							|  |  |  |         memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #ifdef TRIE_COMPACT_PAIRS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         if (arity[arity[0]] == -2 && str[str_index - 1] != '[') | 
					
						
							|  |  |  |           str[str_index - 1] = ','; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         if (arity[arity[0]] == -1) | 
					
						
							|  |  |  |           str[str_index - 1] = '|'; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } while (++bucket != last_bucket); | 
					
						
							|  |  |  |     free(current_arity); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* save current state if first sibling node */ | 
					
						
							|  |  |  |   if (position == TRAVERSE_POSITION_FIRST) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     current_arity = (int *)malloc(sizeof(int) * (arity[0] + 1)); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); | 
					
						
							|  |  |  |     current_str_index = str_index; | 
					
						
							|  |  |  |     current_var_index = var_index; | 
					
						
							|  |  |  |     current_mode = mode; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* print VAR if starting a term */ | 
					
						
							|  |  |  |   if (arity[0] == 0 && mode == TRAVERSE_MODE_NORMAL) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     str_index += sprintf(&str[str_index], "    VAR%d: ", var_index); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     var_index++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* process current trie node */ | 
					
						
							|  |  |  |   TrStat_ans_nodes++; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   traverse_trie_node(TrNode_entry(current_node), str, &str_index, arity, &mode, | 
					
						
							|  |  |  |                      TRAVERSE_TYPE_ANSWER PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* show answer .... */ | 
					
						
							|  |  |  |   if (IS_ANSWER_LEAF_NODE(current_node)) { | 
					
						
							|  |  |  |     TrStat_answers++; | 
					
						
							|  |  |  |     str[str_index] = 0; | 
					
						
							|  |  |  |     SHOW_TABLE_STRUCTURE("%s\n", str); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |   /* ... or continue with pruned node */ | 
					
						
							|  |  |  |   else if (TrNode_child(current_node) == NULL) { | 
					
						
							|  |  |  |     TrStat_answers++; | 
					
						
							|  |  |  |     TrStat_answers_pruned++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							|  |  |  |   /* ... or continue with child node */ | 
					
						
							|  |  |  |   else | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     traverse_answer_trie(TrNode_child(current_node), str, str_index, arity, | 
					
						
							|  |  |  |                          var_index, mode, TRAVERSE_POSITION_FIRST PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* restore the initial state and continue with sibling nodes */ | 
					
						
							|  |  |  |   if (position == TRAVERSE_POSITION_FIRST) { | 
					
						
							|  |  |  |     str_index = current_str_index; | 
					
						
							|  |  |  |     var_index = current_var_index; | 
					
						
							|  |  |  |     mode = current_mode; | 
					
						
							|  |  |  |     current_node = TrNode_next(current_node); | 
					
						
							|  |  |  |     while (current_node) { | 
					
						
							|  |  |  |       memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); | 
					
						
							|  |  |  | #ifdef TRIE_COMPACT_PAIRS
 | 
					
						
							|  |  |  |       if (arity[arity[0]] == -2 && str[str_index - 1] != '[') | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str[str_index - 1] = ','; | 
					
						
							| 
									
										
										
										
											2009-06-24 20:04:16 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |       if (arity[arity[0]] == -1) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str[str_index - 1] = '|'; | 
					
						
							| 
									
										
										
										
											2009-07-05 05:14:08 +01:00
										 |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       traverse_answer_trie(current_node, str, str_index, arity, var_index, mode, | 
					
						
							|  |  |  |                            TRAVERSE_POSITION_NEXT PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |       current_node = TrNode_next(current_node); | 
					
						
							| 
									
										
										
										
											2005-06-03 08:19:18 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     free(current_arity); | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static void traverse_global_trie(gt_node_ptr current_node, char *str, | 
					
						
							|  |  |  |                                  int str_index, int *arity, int mode, | 
					
						
							|  |  |  |                                  int position USES_REGS) { | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   int *current_arity = NULL, current_str_index = 0, current_mode = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* test if hashing */ | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   if (IS_GLOBAL_TRIE_HASH(current_node)) { | 
					
						
							|  |  |  |     gt_node_ptr *bucket, *last_bucket; | 
					
						
							|  |  |  |     gt_hash_ptr hash; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     hash = (gt_hash_ptr)current_node; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     bucket = Hash_buckets(hash); | 
					
						
							|  |  |  |     last_bucket = bucket + Hash_num_buckets(hash); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     current_arity = (int *)malloc(sizeof(int) * (arity[0] + 1)); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       if (*bucket) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         traverse_global_trie(*bucket, str, str_index, arity, mode, | 
					
						
							|  |  |  |                              TRAVERSE_POSITION_FIRST PASS_REGS); | 
					
						
							|  |  |  |         memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #ifdef TRIE_COMPACT_PAIRS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         if (arity[arity[0]] == -2 && str[str_index - 1] != '[') | 
					
						
							|  |  |  |           str[str_index - 1] = ','; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         if (arity[arity[0]] == -1) | 
					
						
							|  |  |  |           str[str_index - 1] = '|'; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } while (++bucket != last_bucket); | 
					
						
							|  |  |  |     free(current_arity); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* save current state if first sibling node */ | 
					
						
							|  |  |  |   if (position == TRAVERSE_POSITION_FIRST) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     current_arity = (int *)malloc(sizeof(int) * (arity[0] + 1)); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); | 
					
						
							|  |  |  |     current_str_index = str_index; | 
					
						
							|  |  |  |     current_mode = mode; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* process current trie node */ | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   TrStat_gt_nodes++; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   traverse_trie_node(TrNode_entry(current_node), str, &str_index, arity, &mode, | 
					
						
							|  |  |  |                      TRAVERSE_TYPE_GT_SUBGOAL PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* continue with child node ... */ | 
					
						
							|  |  |  |   if (arity[0] != 0 || mode != TRAVERSE_MODE_NORMAL) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     traverse_global_trie(TrNode_child(current_node), str, str_index, arity, | 
					
						
							|  |  |  |                          mode, TRAVERSE_POSITION_FIRST PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   /* ... or show term */ | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   else { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     TrStat_gt_terms++; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     str[str_index] = 0; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     SHOW_TABLE_STRUCTURE("  TERMx" UInt_FORMAT ": %s\n", | 
					
						
							|  |  |  |                          (CELL)TrNode_child(current_node), str); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   /* restore the initial state and continue with sibling nodes */ | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   if (position == TRAVERSE_POSITION_FIRST) { | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     str_index = current_str_index; | 
					
						
							|  |  |  |     mode = current_mode; | 
					
						
							|  |  |  |     current_node = TrNode_next(current_node); | 
					
						
							|  |  |  |     while (current_node) { | 
					
						
							|  |  |  |       memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); | 
					
						
							|  |  |  | #ifdef TRIE_COMPACT_PAIRS
 | 
					
						
							|  |  |  |       if (arity[arity[0]] == -2 && str[str_index - 1] != '[') | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str[str_index - 1] = ','; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #else
 | 
					
						
							|  |  |  |       if (arity[arity[0]] == -1) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str[str_index - 1] = '|'; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       traverse_global_trie(current_node, str, str_index, arity, mode, | 
					
						
							|  |  |  |                            TRAVERSE_POSITION_NEXT PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |       current_node = TrNode_next(current_node); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     free(current_arity); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static void traverse_global_trie_for_term(gt_node_ptr current_node, char *str, | 
					
						
							|  |  |  |                                           int *str_index, int *arity, int *mode, | 
					
						
							|  |  |  |                                           int type USES_REGS) { | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   if (TrNode_parent(current_node) != GLOBAL_root_gt) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     traverse_global_trie_for_term(TrNode_parent(current_node), str, str_index, | 
					
						
							|  |  |  |                                   arity, mode, type PASS_REGS); | 
					
						
							|  |  |  |   traverse_trie_node(TrNode_entry(current_node), str, str_index, arity, mode, | 
					
						
							|  |  |  |                      type PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static inline void traverse_trie_node(Term t, char *str, int *str_index_ptr, | 
					
						
							|  |  |  |                                       int *arity, int *mode_ptr, | 
					
						
							|  |  |  |                                       int type USES_REGS) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   int mode = *mode_ptr; | 
					
						
							|  |  |  |   int str_index = *str_index_ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* test the node type */ | 
					
						
							|  |  |  |   if (mode == TRAVERSE_MODE_DOUBLE) { | 
					
						
							|  |  |  | #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
 | 
					
						
							|  |  |  |     arity[0]++; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     arity[arity[0]] = (int)t; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     mode = TRAVERSE_MODE_DOUBLE2; | 
					
						
							|  |  |  |   } else if (mode == TRAVERSE_MODE_DOUBLE2) { | 
					
						
							| 
									
										
										
										
											2011-03-02 23:19:39 +00:00
										 |  |  |     union { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       Term t_dbl[sizeof(Float) / sizeof(Term)]; | 
					
						
							| 
									
										
										
										
											2011-03-02 23:19:39 +00:00
										 |  |  |       Float dbl; | 
					
						
							|  |  |  |     } u; | 
					
						
							|  |  |  |     u.dbl = 0.0; | 
					
						
							|  |  |  |     u.t_dbl[0] = t; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     u.t_dbl[1] = (Term)arity[arity[0]]; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     arity[0]--; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #else  /* SIZEOF_DOUBLE == SIZEOF_INT_P */
 | 
					
						
							| 
									
										
										
										
											2011-03-02 23:19:39 +00:00
										 |  |  |     union { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       Term t_dbl[sizeof(Float) / sizeof(Term)]; | 
					
						
							| 
									
										
										
										
											2011-03-02 23:19:39 +00:00
										 |  |  |       Float dbl; | 
					
						
							|  |  |  |     } u; | 
					
						
							|  |  |  |     u.t_dbl[0] = t; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     str_index += sprintf(&str[str_index], "%.15g", u.dbl); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     traverse_update_arity(str, &str_index, arity); | 
					
						
							|  |  |  |     if (type == TRAVERSE_TYPE_SUBGOAL) | 
					
						
							|  |  |  |       mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     else /* TRAVERSE_TYPE_ANSWER || TRAVERSE_TYPE_GT_SUBGOAL ||
 | 
					
						
							|  |  |  |             TRAVERSE_TYPE_GT_ANSWER */ | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       mode = TRAVERSE_MODE_DOUBLE_END; | 
					
						
							|  |  |  |   } else if (mode == TRAVERSE_MODE_DOUBLE_END) { | 
					
						
							|  |  |  |     mode = TRAVERSE_MODE_NORMAL; | 
					
						
							|  |  |  |   } else if (mode == TRAVERSE_MODE_LONGINT) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     Int li = (Int)t; | 
					
						
							|  |  |  |     str_index += sprintf(&str[str_index], Int_FORMAT, li); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     traverse_update_arity(str, &str_index, arity); | 
					
						
							|  |  |  |     if (type == TRAVERSE_TYPE_SUBGOAL) | 
					
						
							|  |  |  |       mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     else /* TRAVERSE_TYPE_ANSWER || TRAVERSE_TYPE_GT_SUBGOAL ||
 | 
					
						
							|  |  |  |             TRAVERSE_TYPE_GT_ANSWER */ | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       mode = TRAVERSE_MODE_LONGINT_END; | 
					
						
							|  |  |  |   } else if (mode == TRAVERSE_MODE_LONGINT_END) { | 
					
						
							|  |  |  |     mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   } else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING) { | 
					
						
							|  |  |  |     str_index += Yap_OpaqueTermToString(AbsAppl((CELL *)t), str + str_index, 0); | 
					
						
							| 
									
										
										
										
											2014-02-13 11:57:46 +00:00
										 |  |  |     traverse_update_arity(str, &str_index, arity); | 
					
						
							|  |  |  |     if (type == TRAVERSE_TYPE_SUBGOAL) | 
					
						
							|  |  |  |       mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     else /* TRAVERSE_TYPE_ANSWER || TRAVERSE_TYPE_GT_SUBGOAL ||
 | 
					
						
							|  |  |  |             TRAVERSE_TYPE_GT_ANSWER */ | 
					
						
							| 
									
										
										
										
											2014-02-13 11:57:46 +00:00
										 |  |  |       mode = TRAVERSE_MODE_BIGINT_OR_STRING_END; | 
					
						
							|  |  |  |   } else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING_END) { | 
					
						
							|  |  |  |     mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   } else if (IsVarTerm(t)) { | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  | #ifdef TRIE_RATIONAL_TERMS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     if (t > VarIndexOfTableTerm(MAX_TABLE_VARS) && | 
					
						
							|  |  |  |         TrNode_child((gt_node_ptr)t) != | 
					
						
							|  |  |  |             (gt_node_ptr)1) { // TODO: substitute the != 1 test to something
 | 
					
						
							|  |  |  |                               // more appropriate
 | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  |       /* Rational term */ | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       str_index += sprintf(&str[str_index], "**"); | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  |       traverse_update_arity(str, &str_index, arity); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     } else | 
					
						
							| 
									
										
										
										
											2013-12-19 10:56:52 +00:00
										 |  |  | #endif /* RATIONAL TERM SUPPORT FOR TRIES */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         if (t > VarIndexOfTableTerm(MAX_TABLE_VARS)) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       TrStat_gt_refs++; | 
					
						
							|  |  |  |       /* (type % 2 + 2): TRAVERSE_TYPE_ANSWER  --> TRAVERSE_TYPE_GT_ANSWER  */ | 
					
						
							|  |  |  |       /* (type % 2 + 2): TRAVERSE_TYPE_SUBGOAL --> TRAVERSE_TYPE_GT_SUBGOAL */ | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       traverse_global_trie_for_term((gt_node_ptr)t, str, &str_index, arity, | 
					
						
							|  |  |  |                                     &mode, type % 2 + 2 PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       if (type == TRAVERSE_TYPE_SUBGOAL || type == TRAVERSE_TYPE_GT_SUBGOAL) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str_index += sprintf(&str[str_index], "VAR%d", VarIndexOfTableTerm(t)); | 
					
						
							|  |  |  |       else /* TRAVERSE_TYPE_ANSWER || TRAVERSE_TYPE_GT_ANSWER */ | 
					
						
							|  |  |  |         str_index += | 
					
						
							|  |  |  |             sprintf(&str[str_index], "ANSVAR%d", VarIndexOfTableTerm(t)); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       traverse_update_arity(str, &str_index, arity); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else if (IsIntTerm(t)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     str_index += sprintf(&str[str_index], Int_FORMAT, IntOfTerm(t)); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     traverse_update_arity(str, &str_index, arity); | 
					
						
							|  |  |  |   } else if (IsAtomTerm(t)) { | 
					
						
							|  |  |  | #ifndef TRIE_COMPACT_PAIRS
 | 
					
						
							|  |  |  |     if (arity[arity[0]] == -1 && t == TermNil) { | 
					
						
							|  |  |  |       str[str_index - 1] = ']'; | 
					
						
							|  |  |  |       arity[0]--; | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       str_index += sprintf(&str[str_index], "%s", AtomName(AtomOfTerm(t))); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     traverse_update_arity(str, &str_index, arity); | 
					
						
							|  |  |  |   } else if (IsPairTerm(t)) { | 
					
						
							|  |  |  | #ifdef TRIE_COMPACT_PAIRS
 | 
					
						
							|  |  |  |     if (t == CompactPairEndList) | 
					
						
							|  |  |  |       arity[arity[0]] = -1; | 
					
						
							|  |  |  |     else if (t == CompactPairEndTerm) { | 
					
						
							|  |  |  |       str[str_index - 1] = '|'; | 
					
						
							|  |  |  |       arity[arity[0]] = -1; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     if (arity[arity[0]] == -1) { | 
					
						
							|  |  |  |       str[str_index - 1] = ','; | 
					
						
							|  |  |  |       arity[arity[0]] = -2; | 
					
						
							|  |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       str_index += sprintf(&str[str_index], "["); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       arity[0]++; | 
					
						
							|  |  |  |       arity[arity[0]] = -2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else if (IsApplTerm(t)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     Functor f = (Functor)RepAppl(t); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     if (f == FunctorDouble) { | 
					
						
							|  |  |  |       mode = TRAVERSE_MODE_DOUBLE; | 
					
						
							|  |  |  |     } else if (f == FunctorLongInt) { | 
					
						
							|  |  |  |       mode = TRAVERSE_MODE_LONGINT; | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  |     } else if (f == FunctorBigInt || f == FunctorString) { | 
					
						
							|  |  |  |       mode = TRAVERSE_MODE_BIGINT_OR_STRING; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     } else if (f == FunctorComma) { | 
					
						
							|  |  |  |       if (arity[arity[0]] != -3) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str_index += sprintf(&str[str_index], "("); | 
					
						
							|  |  |  |         arity[0]++; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |       arity[arity[0]] = -4; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       str_index += sprintf(&str[str_index], "%s(", AtomName(NameOfFunctor(f))); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       arity[0]++; | 
					
						
							|  |  |  |       arity[arity[0]] = ArityOfFunctor(f); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *mode_ptr = mode; | 
					
						
							|  |  |  |   *str_index_ptr = str_index; | 
					
						
							|  |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static inline void traverse_update_arity(char *str, int *str_index_ptr, | 
					
						
							|  |  |  |                                          int *arity) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   int str_index = *str_index_ptr; | 
					
						
							|  |  |  |   while (arity[0]) { | 
					
						
							|  |  |  |     if (arity[arity[0]] > 0) { | 
					
						
							|  |  |  |       arity[arity[0]]--; | 
					
						
							|  |  |  |       if (arity[arity[0]] == 0) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str_index += sprintf(&str[str_index], ")"); | 
					
						
							|  |  |  |         arity[0]--; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str_index += sprintf(&str[str_index], ","); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       if (arity[arity[0]] == -4) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str_index += sprintf(&str[str_index], ","); | 
					
						
							|  |  |  |         arity[arity[0]] = -3; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       } else if (arity[arity[0]] == -3) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str_index += sprintf(&str[str_index], ")"); | 
					
						
							|  |  |  |         arity[0]--; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       } else if (arity[arity[0]] == -2) { | 
					
						
							|  |  |  | #ifdef TRIE_COMPACT_PAIRS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str_index += sprintf(&str[str_index], ","); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str_index += sprintf(&str[str_index], "|"); | 
					
						
							|  |  |  |         arity[arity[0]] = -1; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #endif /* TRIE_COMPACT_PAIRS */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       } else if (arity[arity[0]] == -1) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         str_index += sprintf(&str[str_index], "]"); | 
					
						
							|  |  |  |         arity[0]--; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   *str_index_ptr = str_index; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | /*******************************
 | 
					
						
							|  |  |  | **      Global functions      ** | 
					
						
							|  |  |  | *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   CELL *stack_vars; | 
					
						
							|  |  |  |   int i, subs_arity, pred_arity; | 
					
						
							|  |  |  |   tab_ent_ptr tab_ent; | 
					
						
							|  |  |  |   sg_fr_ptr sg_fr; | 
					
						
							|  |  |  |   sg_node_ptr current_sg_node; | 
					
						
							| 
									
										
										
										
											2011-11-09 11:00:31 +00:00
										 |  |  | #ifdef MODE_DIRECTED_TABLING
 | 
					
						
							|  |  |  |   int *mode_directed, aux_mode_directed[MAX_TABLE_VARS]; | 
					
						
							|  |  |  |   int subs_pos = 0; | 
					
						
							|  |  |  | #endif /* MODE_DIRECTED_TABLING */
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   stack_vars = *Yaddr; | 
					
						
							|  |  |  |   subs_arity = 0; | 
					
						
							| 
									
										
										
										
											2014-05-30 01:06:09 +01:00
										 |  |  |   pred_arity = preg->y_u.Otapl.s; | 
					
						
							|  |  |  |   tab_ent = preg->y_u.Otapl.te; | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   current_sg_node = get_insert_subgoal_trie(tab_ent PASS_REGS); | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  |   LOCK_SUBGOAL_TRIE(tab_ent); | 
					
						
							| 
									
										
										
										
											2010-04-03 16:05:38 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-22 16:49:13 +01:00
										 |  |  | #ifdef MODE_DIRECTED_TABLING
 | 
					
						
							| 
									
										
										
										
											2011-11-09 11:00:31 +00:00
										 |  |  |   mode_directed = TabEnt_mode_directed(tab_ent); | 
					
						
							|  |  |  |   if (mode_directed) { | 
					
						
							|  |  |  |     int old_subs_arity = subs_arity; | 
					
						
							|  |  |  |     for (i = 1; i <= pred_arity; i++) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       int j = MODE_DIRECTED_GET_ARG(mode_directed[i - 1]) + 1; | 
					
						
							|  |  |  |       current_sg_node = | 
					
						
							|  |  |  |           subgoal_search_loop(tab_ent, current_sg_node, Deref(XREGS[j]), | 
					
						
							|  |  |  |                               &subs_arity, &stack_vars PASS_REGS); | 
					
						
							| 
									
										
										
										
											2011-11-09 11:00:31 +00:00
										 |  |  |       if (subs_arity != old_subs_arity) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         if (subs_pos && | 
					
						
							|  |  |  |             MODE_DIRECTED_GET_MODE(aux_mode_directed[subs_pos - 1]) == | 
					
						
							|  |  |  |                 MODE_DIRECTED_GET_MODE(mode_directed[i - 1])) { | 
					
						
							|  |  |  |           /* same mode as before -> use the current entry in the
 | 
					
						
							|  |  |  |            * aux_mode_directed[] array */ | 
					
						
							|  |  |  |           aux_mode_directed[subs_pos - 1] += | 
					
						
							|  |  |  |               MODE_DIRECTED_SET(subs_arity - old_subs_arity, 0); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           /* new mode -> init a new entry in the aux_mode_directed[] array */ | 
					
						
							|  |  |  |           aux_mode_directed[subs_pos] = | 
					
						
							|  |  |  |               MODE_DIRECTED_SET(subs_arity - old_subs_arity, | 
					
						
							|  |  |  |                                 MODE_DIRECTED_GET_MODE(mode_directed[i - 1])); | 
					
						
							|  |  |  |           subs_pos++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         old_subs_arity = subs_arity; | 
					
						
							| 
									
										
										
										
											2011-11-09 11:00:31 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else | 
					
						
							|  |  |  | #endif /* MODE_DIRECTED_TABLING */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       if (IsMode_GlobalTrie(TabEnt_mode(tab_ent))) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     for (i = 1; i <= pred_arity; i++) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       current_sg_node = | 
					
						
							|  |  |  |           subgoal_search_terms_loop(tab_ent, current_sg_node, Deref(XREGS[i]), | 
					
						
							|  |  |  |                                     &subs_arity, &stack_vars PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2011-11-09 11:00:31 +00:00
										 |  |  |     for (i = 1; i <= pred_arity; i++) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       current_sg_node = | 
					
						
							|  |  |  |           subgoal_search_loop(tab_ent, current_sg_node, Deref(XREGS[i]), | 
					
						
							|  |  |  |                               &subs_arity, &stack_vars PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   STACK_PUSH_UP(subs_arity, stack_vars); | 
					
						
							|  |  |  |   *Yaddr = stack_vars++; | 
					
						
							|  |  |  |   /* reset variables */ | 
					
						
							|  |  |  |   while (subs_arity--) { | 
					
						
							|  |  |  |     Term t = STACK_POP_DOWN(stack_vars); | 
					
						
							|  |  |  |     RESET_VARIABLE(t); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   sg_fr_ptr *sg_fr_end = | 
					
						
							|  |  |  |       get_insert_subgoal_frame_addr(current_sg_node PASS_REGS); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #ifndef THREADS
 | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  |   LOCK_SUBGOAL_NODE(current_sg_node); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #endif /* !THREADS */
 | 
					
						
							|  |  |  |   if (*sg_fr_end == NULL) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | /* new tabled subgoal */ | 
					
						
							| 
									
										
										
										
											2011-10-22 16:49:13 +01:00
										 |  |  | #ifdef MODE_DIRECTED_TABLING
 | 
					
						
							| 
									
										
										
										
											2011-11-09 14:24:08 +00:00
										 |  |  |     if (subs_pos) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       ALLOC_BLOCK(mode_directed, subs_pos * sizeof(int), int); | 
					
						
							|  |  |  |       memcpy((void *)mode_directed, (void *)aux_mode_directed, | 
					
						
							|  |  |  |              subs_pos * sizeof(int)); | 
					
						
							| 
									
										
										
										
											2011-11-09 14:24:08 +00:00
										 |  |  |     } else | 
					
						
							|  |  |  |       mode_directed = NULL; | 
					
						
							| 
									
										
										
										
											2011-11-09 11:00:31 +00:00
										 |  |  | #endif /* MODE_DIRECTED_TABLING */
 | 
					
						
							| 
									
										
										
										
											2012-01-05 11:41:46 +00:00
										 |  |  | #if !defined(THREADS_FULL_SHARING) && !defined(THREADS_CONSUMER_SHARING)
 | 
					
						
							| 
									
										
										
										
											2011-11-09 11:00:31 +00:00
										 |  |  |     new_subgoal_frame(sg_fr, preg, mode_directed); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     *sg_fr_end = sg_fr; | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  |     __sync_synchronize(); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     TAG_AS_SUBGOAL_LEAF_NODE(current_sg_node); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     UNLOCK_SUBGOAL_NODE(current_sg_node); | 
					
						
							| 
									
										
										
										
											2012-01-05 11:41:46 +00:00
										 |  |  | #else /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     sg_ent_ptr sg_ent = | 
					
						
							|  |  |  |         (sg_ent_ptr)UNTAG_SUBGOAL_NODE(TrNode_sg_ent(current_sg_node)); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     new_subgoal_frame(sg_fr, sg_ent); | 
					
						
							|  |  |  | #ifdef THREADS_CONSUMER_SHARING
 | 
					
						
							|  |  |  |     SgFr_state(sg_fr) = ready_external; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     SgFr_state(sg_fr) = ready; | 
					
						
							|  |  |  | #endif /* THREADS_CONSUMER_SHARING */
 | 
					
						
							| 
									
										
										
										
											2012-01-05 11:41:46 +00:00
										 |  |  |     if (SgEnt_sg_ent_state(sg_ent) == ready) { | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |       LOCK(SgEnt_lock(sg_ent)); | 
					
						
							| 
									
										
										
										
											2012-01-05 11:41:46 +00:00
										 |  |  |       if (SgEnt_sg_ent_state(sg_ent) == ready) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         SgEnt_code(sg_ent) = preg; | 
					
						
							|  |  |  |         SgEnt_init_mode_directed_fields(sg_ent, mode_directed); | 
					
						
							|  |  |  |         SgEnt_sg_ent_state(sg_ent) = evaluating; | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #ifdef THREADS_CONSUMER_SHARING
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         SgEnt_gen_worker(sg_ent) = worker_id; | 
					
						
							|  |  |  |         SgFr_state(sg_fr) = ready; | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #endif /* THREADS_CONSUMER_SHARING */
 | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       UNLOCK(SgEnt_lock(sg_ent)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     *sg_fr_end = sg_fr; | 
					
						
							| 
									
										
										
										
											2012-01-05 11:41:46 +00:00
										 |  |  | #endif /* !THREADS_FULL_SHARING && !THREADS_CONSUMER_SHARING */
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | /* repeated tabled subgoal */ | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #ifndef THREADS
 | 
					
						
							|  |  |  |     UNLOCK_SUBGOAL_NODE(current_sg_node); | 
					
						
							|  |  |  | #endif /* !THREADS */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     sg_fr = (sg_fr_ptr)UNTAG_SUBGOAL_NODE(*sg_fr_end); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #ifdef LIMIT_TABLING
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     if (SgFr_state(sg_fr) <= ready) { /* incomplete or ready */ | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |       remove_from_global_sg_fr_list(sg_fr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif /* LIMIT_TABLING */
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  |   UNLOCK_SUBGOAL_TRIE(tab_ent); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   return sg_fr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) { | 
					
						
							|  |  |  | #define subs_arity *subs_ptr
 | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   CELL *stack_vars; | 
					
						
							|  |  |  |   int i, vars_arity; | 
					
						
							|  |  |  |   ans_node_ptr current_ans_node; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   vars_arity = 0; | 
					
						
							|  |  |  |   current_ans_node = SgFr_answer_trie(sg_fr); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   if (IsMode_GlobalTrie(TabEnt_mode(SgFr_tab_ent(sg_fr)))) { | 
					
						
							|  |  |  |     for (i = subs_arity; i >= 1; i--) { | 
					
						
							| 
									
										
										
										
											2011-11-11 18:05:24 +00:00
										 |  |  |       TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i])); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       current_ans_node = answer_search_terms_loop( | 
					
						
							|  |  |  |           sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     for (i = subs_arity; i >= 1; i--) { | 
					
						
							| 
									
										
										
										
											2011-11-11 18:05:24 +00:00
										 |  |  |       TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i])); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       current_ans_node = answer_search_loop( | 
					
						
							|  |  |  |           sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* reset variables */ | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   stack_vars = (CELL *)TR; | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   while (vars_arity--) { | 
					
						
							|  |  |  |     Term t = STACK_POP_DOWN(stack_vars); | 
					
						
							|  |  |  |     RESET_VARIABLE(t); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return current_ans_node; | 
					
						
							|  |  |  | #undef subs_arity
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  | #ifdef MODE_DIRECTED_TABLING
 | 
					
						
							|  |  |  | ans_node_ptr mode_directed_answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) { | 
					
						
							|  |  |  | #define subs_arity *subs_ptr
 | 
					
						
							|  |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   CELL *stack_vars; | 
					
						
							|  |  |  |   int i, j, vars_arity; | 
					
						
							|  |  |  |   ans_node_ptr current_ans_node, invalid_ans_node; | 
					
						
							|  |  |  |   int *mode_directed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   vars_arity = 0; | 
					
						
							|  |  |  |   current_ans_node = SgFr_answer_trie(sg_fr); | 
					
						
							|  |  |  |   invalid_ans_node = NULL; | 
					
						
							|  |  |  |   mode_directed = SgFr_mode_directed(sg_fr); | 
					
						
							|  |  |  |   j = 0; | 
					
						
							|  |  |  |   i = subs_arity; | 
					
						
							|  |  |  |   while (i) { | 
					
						
							|  |  |  |     int mode = MODE_DIRECTED_GET_MODE(mode_directed[j]); | 
					
						
							|  |  |  |     int n_subs = MODE_DIRECTED_GET_ARG(mode_directed[j]); | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i])); | 
					
						
							| 
									
										
										
										
											2011-11-16 11:42:04 +00:00
										 |  |  |       if (mode == MODE_DIRECTED_INDEX || mode == MODE_DIRECTED_ALL) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         current_ans_node = answer_search_loop( | 
					
						
							|  |  |  |             sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity PASS_REGS); | 
					
						
							| 
									
										
										
										
											2011-11-16 11:42:04 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         LOCK_ANSWER_NODE(current_ans_node); | 
					
						
							|  |  |  |         if (TrNode_child(current_ans_node) == NULL) { | 
					
						
							| 
									
										
										
										
											2012-06-06 15:19:38 +01:00
										 |  |  | #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |           struct answer_trie_node | 
					
						
							|  |  |  |               virtual_ans_node; /* necessary because the answer_search_loop()
 | 
					
						
							|  |  |  |                                    procedure also locks the parent node */ | 
					
						
							|  |  |  |           ans_node_ptr parent_ans_node = current_ans_node; | 
					
						
							|  |  |  |           AnsNode_init_lock_field(&virtual_ans_node); | 
					
						
							|  |  |  |           TrNode_parent(&virtual_ans_node) = NULL; | 
					
						
							|  |  |  |           TrNode_child(&virtual_ans_node) = NULL; | 
					
						
							|  |  |  |           current_ans_node = | 
					
						
							|  |  |  |               answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), | 
					
						
							|  |  |  |                                  &vars_arity PASS_REGS); | 
					
						
							|  |  |  |           TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node); | 
					
						
							|  |  |  |           TrNode_parent(TrNode_child(&virtual_ans_node)) = parent_ans_node; | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |           current_ans_node = | 
					
						
							|  |  |  |               answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), | 
					
						
							|  |  |  |                                  &vars_arity PASS_REGS); | 
					
						
							| 
									
										
										
										
											2012-06-06 15:19:38 +01:00
										 |  |  | #endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         } else if (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX) { | 
					
						
							|  |  |  |           ans_node_ptr parent_ans_node = current_ans_node; | 
					
						
							|  |  |  |           invalid_ans_node = TrNode_child( | 
					
						
							|  |  |  |               parent_ans_node); /* by default, assume a better answer */ | 
					
						
							|  |  |  |           current_ans_node = answer_search_min_max( | 
					
						
							|  |  |  |               sg_fr, current_ans_node, Deref(subs_ptr[i]), mode PASS_REGS); | 
					
						
							|  |  |  |           if (invalid_ans_node == | 
					
						
							|  |  |  |               TrNode_child(parent_ans_node)) /* worse or equal answer */ | 
					
						
							|  |  |  |             invalid_ans_node = NULL; | 
					
						
							|  |  |  |         } else if (mode == MODE_DIRECTED_SUM) { | 
					
						
							|  |  |  |           invalid_ans_node = TrNode_child(current_ans_node); | 
					
						
							|  |  |  |           current_ans_node = answer_search_sum(sg_fr, current_ans_node, | 
					
						
							|  |  |  |                                                Deref(subs_ptr[i]) PASS_REGS); | 
					
						
							|  |  |  |         } else if (mode == MODE_DIRECTED_LAST) { | 
					
						
							| 
									
										
										
										
											2012-06-06 15:19:38 +01:00
										 |  |  | #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |           struct answer_trie_node | 
					
						
							|  |  |  |               virtual_ans_node; /* necessary because the answer_search_loop()
 | 
					
						
							|  |  |  |                                    procedure also locks the parent node */ | 
					
						
							|  |  |  |           ans_node_ptr parent_ans_node = current_ans_node; | 
					
						
							|  |  |  |           invalid_ans_node = TrNode_child(parent_ans_node); | 
					
						
							|  |  |  |           AnsNode_init_lock_field(&virtual_ans_node); | 
					
						
							|  |  |  |           TrNode_parent(&virtual_ans_node) = NULL; | 
					
						
							|  |  |  |           TrNode_child(&virtual_ans_node) = NULL; | 
					
						
							|  |  |  |           current_ans_node = | 
					
						
							|  |  |  |               answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), | 
					
						
							|  |  |  |                                  &vars_arity PASS_REGS); | 
					
						
							|  |  |  |           TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node); | 
					
						
							|  |  |  |           TrNode_parent(TrNode_child(&virtual_ans_node)) = parent_ans_node; | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |           invalid_ans_node = TrNode_child(current_ans_node); | 
					
						
							|  |  |  |           TrNode_child(current_ans_node) = NULL; | 
					
						
							|  |  |  |           current_ans_node = | 
					
						
							|  |  |  |               answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), | 
					
						
							|  |  |  |                                  &vars_arity PASS_REGS); | 
					
						
							| 
									
										
										
										
											2012-06-06 15:19:38 +01:00
										 |  |  | #endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         } else if (mode == MODE_DIRECTED_FIRST) { | 
					
						
							|  |  |  |           current_ans_node = NULL; | 
					
						
							|  |  |  |         } else | 
					
						
							|  |  |  |           Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, | 
					
						
							|  |  |  |                     "mode_directed_answer_search: unknown mode"); | 
					
						
							|  |  |  |         UNLOCK_ANSWER_NODE(current_ans_node); | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       n_subs--; | 
					
						
							|  |  |  |       i--; | 
					
						
							|  |  |  |     } while (n_subs && current_ans_node); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     if (current_ans_node == NULL) /* no answer inserted */ | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  |       break; | 
					
						
							|  |  |  |     j++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (invalid_ans_node) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     invalidate_answer_trie(invalid_ans_node, sg_fr, | 
					
						
							|  |  |  |                            TRAVERSE_POSITION_FIRST PASS_REGS); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  |   /* reset variables */ | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   stack_vars = (CELL *)TR; | 
					
						
							| 
									
										
										
										
											2011-11-15 16:57:51 +00:00
										 |  |  |   while (vars_arity--) { | 
					
						
							|  |  |  |     Term t = STACK_POP_DOWN(stack_vars); | 
					
						
							|  |  |  |     RESET_VARIABLE(t); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return current_ans_node; | 
					
						
							|  |  |  | #undef subs_arity
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif /* MODE_DIRECTED_TABLING */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | void load_answer(ans_node_ptr current_ans_node, CELL *subs_ptr) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #define subs_arity *subs_ptr
 | 
					
						
							|  |  |  |   CELL *stack_terms; | 
					
						
							|  |  |  |   int i; | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-18 04:59:11 +01:00
										 |  |  |   TABLING_ERROR_CHECKING(load_answer, H < H_FZ); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   if (subs_arity == 0) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  |   stack_terms = load_answer_loop(current_ans_node PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   for (i = subs_arity; i >= 1; i--) { | 
					
						
							|  |  |  |     Term t = STACK_POP_DOWN(stack_terms); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     YapBind((CELL *)subs_ptr[i], t); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  |   TABLING_ERROR_CHECKING(load_answer, stack_terms != (CELL *)LOCAL_TrailTop); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return; | 
					
						
							|  |  |  | #undef subs_arity
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-15 01:09:59 +01:00
										 |  |  | CELL *exec_substitution(gt_node_ptr current_node, CELL *aux_stack) { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  | #define subs_arity *subs_ptr
 | 
					
						
							| 
									
										
										
										
											2010-04-15 01:09:59 +01:00
										 |  |  |   CELL *stack_terms, *subs_ptr; | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   Term t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   ++aux_stack; /* skip the heap_arity entry */ | 
					
						
							|  |  |  |   stack_terms = exec_substitution_loop(current_node, &aux_stack, | 
					
						
							|  |  |  |                                        (CELL *)LOCAL_TrailTop PASS_REGS); | 
					
						
							|  |  |  |   *--aux_stack = 0; /* restore the heap_arity entry */ | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-15 01:09:59 +01:00
										 |  |  |   subs_ptr = aux_stack + aux_stack[1] + 2; | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   t = STACK_POP_DOWN(stack_terms); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   YapBind((CELL *)subs_ptr[subs_arity], t); | 
					
						
							|  |  |  |   TABLING_ERROR_CHECKING(exec_substitution, | 
					
						
							|  |  |  |                          stack_terms != (CELL *)LOCAL_TrailTop); | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  |   *subs_ptr = subs_arity - 1; | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-15 01:09:59 +01:00
										 |  |  |   return aux_stack; | 
					
						
							| 
									
										
										
										
											2010-04-05 03:34:02 +01:00
										 |  |  | #undef subs_arity
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  | void update_answer_trie(sg_fr_ptr sg_fr) { | 
					
						
							|  |  |  |   ans_node_ptr current_node; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   free_answer_hash_chain(SgFr_hash_chain(sg_fr)); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   SgFr_hash_chain(sg_fr) = NULL; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   SgFr_state(sg_fr) += | 
					
						
							|  |  |  |       2; /* complete --> compiled : complete_in_use --> compiled_in_use */ | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   SgFr_sg_ent_state(sg_fr) += 2; /* complete --> compiled */ | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #ifdef THREADS_FULL_SHARING
 | 
					
						
							|  |  |  |   if (IsMode_Batched(TabEnt_mode(SgFr_tab_ent(sg_fr)))) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     /* cleaning bits used by batched mode and shifting the instruction back to
 | 
					
						
							|  |  |  |      * the original place */ | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     ans_node_ptr leaf_ans_trie_node = SgFr_first_answer(sg_fr); | 
					
						
							|  |  |  |     while (TrNode_child(leaf_ans_trie_node) != NULL) { | 
					
						
							|  |  |  |       ANSWER_LEAF_NODE_INSTR_ABSOLUTE(leaf_ans_trie_node); | 
					
						
							|  |  |  |       leaf_ans_trie_node = TrNode_child(leaf_ans_trie_node); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ANSWER_LEAF_NODE_INSTR_ABSOLUTE(leaf_ans_trie_node); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* THREADS_FULL_SHARING */
 | 
					
						
							|  |  |  | #endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
 | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   current_node = TrNode_child(SgFr_answer_trie(sg_fr)); | 
					
						
							|  |  |  |   if (current_node) { | 
					
						
							|  |  |  | #ifdef YAPOR
 | 
					
						
							|  |  |  |     TrNode_instr(current_node) -= 1; | 
					
						
							|  |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							|  |  |  |     update_answer_trie_branch(NULL, current_node); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     update_answer_trie_branch(current_node); | 
					
						
							|  |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #else  /* TABLING */
 | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     update_answer_trie_branch(current_node, TRAVERSE_POSITION_FIRST); | 
					
						
							|  |  |  | #endif /* YAPOR */
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | void free_subgoal_trie(sg_node_ptr current_node, int mode, int position) { | 
					
						
							| 
									
										
										
										
											2011-12-07 13:53:20 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   if (IS_SUBGOAL_TRIE_HASH(current_node)) { | 
					
						
							|  |  |  |     sg_node_ptr *bucket, *last_bucket; | 
					
						
							|  |  |  |     sg_hash_ptr hash; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     hash = (sg_hash_ptr)current_node; | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     bucket = Hash_buckets(hash); | 
					
						
							|  |  |  |     last_bucket = bucket + Hash_num_buckets(hash); | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       if (*bucket) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         sg_node_ptr next_node = *bucket; | 
					
						
							|  |  |  |         do { | 
					
						
							|  |  |  |           current_node = next_node; | 
					
						
							|  |  |  |           next_node = TrNode_next(current_node); | 
					
						
							|  |  |  |           free_subgoal_trie(current_node, mode, TRAVERSE_POSITION_NEXT); | 
					
						
							|  |  |  |         } while (next_node); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |     } while (++bucket != last_bucket); | 
					
						
							|  |  |  |     IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES { | 
					
						
							|  |  |  |       FREE_BUCKETS(Hash_buckets(hash)); | 
					
						
							|  |  |  |       FREE_SUBGOAL_TRIE_HASH(hash); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   if (!IS_SUBGOAL_LEAF_NODE(current_node)) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     int child_mode; | 
					
						
							|  |  |  |     if (mode == TRAVERSE_MODE_NORMAL) { | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |       Term t = TrNode_entry(current_node); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       if (IsApplTerm(t)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         Functor f = (Functor)RepAppl(t); | 
					
						
							|  |  |  |         if (f == FunctorDouble) | 
					
						
							|  |  |  |           child_mode = TRAVERSE_MODE_DOUBLE; | 
					
						
							|  |  |  |         else if (f == FunctorLongInt) | 
					
						
							|  |  |  |           child_mode = TRAVERSE_MODE_LONGINT; | 
					
						
							|  |  |  |         else if (f == FunctorBigInt || f == FunctorString) | 
					
						
							|  |  |  |           child_mode = TRAVERSE_MODE_BIGINT_OR_STRING; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           child_mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       } else | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         child_mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  |     } else if (mode == TRAVERSE_MODE_LONGINT) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       child_mode = TRAVERSE_MODE_LONGINT_END; | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  |     } else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING) { | 
					
						
							|  |  |  |       Yap_FreeCodeSpace((char *)TrNode_entry(current_node)); | 
					
						
							|  |  |  |       child_mode = TRAVERSE_MODE_BIGINT_OR_STRING_END; | 
					
						
							|  |  |  |     } else if (mode == TRAVERSE_MODE_DOUBLE) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
 | 
					
						
							|  |  |  |       child_mode = TRAVERSE_MODE_DOUBLE2; | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  |     } else if (mode == TRAVERSE_MODE_DOUBLE2) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
 | 
					
						
							|  |  |  |       child_mode = TRAVERSE_MODE_DOUBLE_END; | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       child_mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     free_subgoal_trie(TrNode_child(current_node), child_mode, | 
					
						
							|  |  |  |                       TRAVERSE_POSITION_FIRST); | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     sg_fr_ptr sg_fr = get_subgoal_frame_for_abolish(current_node PASS_REGS); | 
					
						
							|  |  |  |     if (sg_fr) { | 
					
						
							|  |  |  |       ans_node_ptr ans_node; | 
					
						
							|  |  |  |       free_answer_hash_chain(SgFr_hash_chain(sg_fr)); | 
					
						
							|  |  |  |       ans_node = SgFr_answer_trie(sg_fr); | 
					
						
							|  |  |  |       if (TrNode_child(ans_node)) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         free_answer_trie(TrNode_child(ans_node), TRAVERSE_MODE_NORMAL, | 
					
						
							|  |  |  |                          TRAVERSE_POSITION_FIRST); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |       IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         FREE_ANSWER_TRIE_NODE(ans_node); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
 | 
					
						
							| 
									
										
										
										
											2012-06-04 19:27:31 +01:00
										 |  |  | #ifdef MODE_DIRECTED_TABLING
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         if (SgEnt_mode_directed(SgFr_sg_ent(sg_fr))) | 
					
						
							|  |  |  |           FREE_BLOCK(SgEnt_mode_directed(SgFr_sg_ent(sg_fr))); | 
					
						
							|  |  |  |         if (SgFr_invalid_chain(sg_fr)) { | 
					
						
							|  |  |  |           ans_node_ptr current_node, next_node; | 
					
						
							|  |  |  |           /* free invalid answer nodes */ | 
					
						
							|  |  |  |           current_node = SgFr_invalid_chain(sg_fr); | 
					
						
							|  |  |  |           SgFr_invalid_chain(sg_fr) = NULL; | 
					
						
							|  |  |  |           while (current_node) { | 
					
						
							|  |  |  |             next_node = TrNode_next(current_node); | 
					
						
							|  |  |  |             FREE_ANSWER_TRIE_NODE(current_node); | 
					
						
							|  |  |  |             current_node = next_node; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2012-06-04 19:27:31 +01:00
										 |  |  | #endif /* MODE_DIRECTED_TABLING */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         FREE_SUBGOAL_ENTRY(SgFr_sg_ent(sg_fr)); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
 | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #ifdef LIMIT_TABLING
 | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |       remove_from_global_sg_fr_list(sg_fr); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #endif /* LIMIT_TABLING */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #if defined(MODE_DIRECTED_TABLING) && !defined(THREADS_FULL_SHARING) &&        \
 | 
					
						
							|  |  |  |     !defined(THREADS_CONSUMER_SHARING) | 
					
						
							| 
									
										
										
										
											2012-06-04 19:27:31 +01:00
										 |  |  |       if (SgFr_mode_directed(sg_fr)) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         FREE_BLOCK(SgFr_mode_directed(sg_fr)); | 
					
						
							|  |  |  | #endif /* MODE_DIRECTED_TABLING && !THREADS_FULL_SHARING &&                    \
 | 
					
						
							|  |  |  |           !THREADS_CONSUMER_SHARING */ | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |       FREE_SUBGOAL_FRAME(sg_fr); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   if (position == TRAVERSE_POSITION_FIRST) { | 
					
						
							|  |  |  |     sg_node_ptr next_node = TrNode_next(current_node); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES { | 
					
						
							|  |  |  |       CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode); | 
					
						
							|  |  |  |       FREE_SUBGOAL_TRIE_NODE(current_node); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     while (next_node) { | 
					
						
							|  |  |  |       current_node = next_node; | 
					
						
							|  |  |  |       next_node = TrNode_next(current_node); | 
					
						
							|  |  |  |       free_subgoal_trie(current_node, mode, TRAVERSE_POSITION_NEXT); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES { | 
					
						
							|  |  |  |       CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode); | 
					
						
							|  |  |  |       FREE_SUBGOAL_TRIE_NODE(current_node); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | void free_answer_trie(ans_node_ptr current_node, int mode, int position) { | 
					
						
							| 
									
										
										
										
											2011-12-07 13:53:20 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   if (!IS_ANSWER_LEAF_NODE(current_node) && TrNode_child(current_node)) { | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   if (!IS_ANSWER_LEAF_NODE(current_node)) { | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |     int child_mode; | 
					
						
							|  |  |  |     if (mode == TRAVERSE_MODE_NORMAL) { | 
					
						
							|  |  |  |       Term t = TrNode_entry(current_node); | 
					
						
							|  |  |  |       if (IsApplTerm(t)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         Functor f = (Functor)RepAppl(t); | 
					
						
							|  |  |  |         if (f == FunctorDouble) | 
					
						
							|  |  |  |           child_mode = TRAVERSE_MODE_DOUBLE; | 
					
						
							|  |  |  |         else if (f == FunctorLongInt) | 
					
						
							|  |  |  |           child_mode = TRAVERSE_MODE_LONGINT; | 
					
						
							|  |  |  |         else if (f == FunctorBigInt || f == FunctorString) | 
					
						
							|  |  |  |           child_mode = TRAVERSE_MODE_BIGINT_OR_STRING; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           child_mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       } else | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         child_mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  |     } else if (mode == TRAVERSE_MODE_LONGINT) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       child_mode = TRAVERSE_MODE_LONGINT_END; | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  |     } else if (mode == TRAVERSE_MODE_BIGINT_OR_STRING) { | 
					
						
							|  |  |  |       Yap_FreeCodeSpace((char *)TrNode_entry(current_node)); | 
					
						
							|  |  |  |       child_mode = TRAVERSE_MODE_BIGINT_OR_STRING_END; | 
					
						
							|  |  |  |     } else if (mode == TRAVERSE_MODE_DOUBLE) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P
 | 
					
						
							|  |  |  |       child_mode = TRAVERSE_MODE_DOUBLE2; | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  |     } else if (mode == TRAVERSE_MODE_DOUBLE2) { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  | #endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */
 | 
					
						
							|  |  |  |       child_mode = TRAVERSE_MODE_DOUBLE_END; | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       child_mode = TRAVERSE_MODE_NORMAL; | 
					
						
							| 
									
										
										
										
											2014-01-17 09:39:29 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     free_answer_trie(TrNode_child(current_node), child_mode, | 
					
						
							|  |  |  |                      TRAVERSE_POSITION_FIRST); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   if (position == TRAVERSE_POSITION_FIRST) { | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |     ans_node_ptr next_node = TrNode_next(current_node); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES { | 
					
						
							|  |  |  |       CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode); | 
					
						
							|  |  |  |       FREE_ANSWER_TRIE_NODE(current_node); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |     while (next_node) { | 
					
						
							|  |  |  |       current_node = next_node; | 
					
						
							|  |  |  |       next_node = TrNode_next(current_node); | 
					
						
							| 
									
										
										
										
											2010-04-23 04:22:10 +01:00
										 |  |  |       free_answer_trie(current_node, mode, TRAVERSE_POSITION_NEXT); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES { | 
					
						
							|  |  |  |       CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode); | 
					
						
							|  |  |  |       FREE_ANSWER_TRIE_NODE(current_node); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | void free_answer_hash_chain(ans_hash_ptr hash) { | 
					
						
							| 
									
										
										
										
											2012-01-05 11:41:46 +00:00
										 |  |  | #if defined(THREADS_NO_SHARING) || defined(THREADS_SUBGOAL_SHARING)
 | 
					
						
							| 
									
										
										
										
											2011-12-07 13:53:20 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2012-01-05 11:41:46 +00:00
										 |  |  | #endif /* THREADS_NO_SHARING || THREADS_SUBGOAL_SHARING */
 | 
					
						
							| 
									
										
										
										
											2011-12-07 13:53:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |   while (hash) { | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     ans_node_ptr chain_node, *bucket, *last_bucket; | 
					
						
							|  |  |  |     ans_hash_ptr next_hash; | 
					
						
							| 
									
										
										
										
											2009-08-05 05:48:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     bucket = Hash_buckets(hash); | 
					
						
							|  |  |  |     last_bucket = bucket + Hash_num_buckets(hash); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     while (!*bucket) | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |       bucket++; | 
					
						
							|  |  |  |     chain_node = *bucket; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     TrNode_child((ans_node_ptr)UNTAG_ANSWER_NODE(TrNode_parent(chain_node))) = | 
					
						
							|  |  |  |         chain_node; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     while (++bucket != last_bucket) { | 
					
						
							|  |  |  |       if (*bucket) { | 
					
						
							|  |  |  |         while (TrNode_next(chain_node)) | 
					
						
							|  |  |  |           chain_node = TrNode_next(chain_node); | 
					
						
							|  |  |  |         TrNode_next(chain_node) = *bucket; | 
					
						
							|  |  |  |         chain_node = *bucket; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     next_hash = Hash_next(hash); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     FREE_BUCKETS(Hash_buckets(hash)); | 
					
						
							|  |  |  |     FREE_ANSWER_TRIE_HASH(hash); | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     hash = next_hash; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  | /*****************************************************************************************
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | ** all threads abolish their local data structures, and the main thread also | 
					
						
							|  |  |  | *abolishes  ** | 
					
						
							|  |  |  | ** all shared data structures, if no other thread is running (GLOBAL_NOfThreads | 
					
						
							|  |  |  | *== 1).  ** | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  | *****************************************************************************************/ | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | void abolish_table(tab_ent_ptr tab_ent) { | 
					
						
							| 
									
										
										
										
											2011-12-07 13:53:20 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   sg_node_ptr sg_node; | 
					
						
							| 
									
										
										
										
											2011-12-07 13:53:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-22 14:47:47 +01:00
										 |  |  | #ifdef THREADS
 | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  |   if (GLOBAL_NOfThreads == 1) { | 
					
						
							|  |  |  |     ATTACH_PAGES(_pages_tab_ent); | 
					
						
							|  |  |  | #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
 | 
					
						
							|  |  |  |     ATTACH_PAGES(_pages_sg_ent); | 
					
						
							|  |  |  | #endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
 | 
					
						
							|  |  |  |     ATTACH_PAGES(_pages_sg_fr); | 
					
						
							|  |  |  |     ATTACH_PAGES(_pages_dep_fr); | 
					
						
							|  |  |  |     ATTACH_PAGES(_pages_sg_node); | 
					
						
							|  |  |  |     ATTACH_PAGES(_pages_sg_hash); | 
					
						
							|  |  |  |     ATTACH_PAGES(_pages_ans_node); | 
					
						
							|  |  |  |     ATTACH_PAGES(_pages_ans_hash); | 
					
						
							|  |  |  | #if defined(THREADS_FULL_SHARING)
 | 
					
						
							|  |  |  |     ATTACH_PAGES(_pages_ans_ref_node); | 
					
						
							|  |  |  | #endif /* THREADS_FULL_SHARING */
 | 
					
						
							|  |  |  |     ATTACH_PAGES(_pages_gt_node); | 
					
						
							|  |  |  |     ATTACH_PAGES(_pages_gt_hash); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-05-22 14:47:47 +01:00
										 |  |  | #endif /* THREADS */
 | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   sg_node = get_subgoal_trie_for_abolish(tab_ent PASS_REGS); | 
					
						
							|  |  |  |   if (sg_node) { | 
					
						
							|  |  |  |     if (TrNode_child(sg_node)) { | 
					
						
							|  |  |  |       if (TabEnt_arity(tab_ent)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         free_subgoal_trie(TrNode_child(sg_node), TRAVERSE_MODE_NORMAL, | 
					
						
							|  |  |  |                           TRAVERSE_POSITION_FIRST); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         sg_fr_ptr sg_fr = get_subgoal_frame_for_abolish(sg_node PASS_REGS); | 
					
						
							|  |  |  |         if (sg_fr) { | 
					
						
							|  |  |  |           IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES { | 
					
						
							|  |  |  |             FREE_ANSWER_TRIE_NODE(SgFr_answer_trie(sg_fr)); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |             FREE_SUBGOAL_ENTRY(SgFr_sg_ent(sg_fr)); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #ifdef LIMIT_TABLING
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |           remove_from_global_sg_fr_list(sg_fr); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #endif /* LIMIT_TABLING */
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |           FREE_SUBGOAL_FRAME(sg_fr); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |       IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |       TrNode_child(sg_node) = NULL; | 
					
						
							| 
									
										
										
										
											2010-04-19 02:34:08 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #ifdef THREADS_NO_SHARING
 | 
					
						
							|  |  |  |     FREE_SUBGOAL_TRIE_NODE(sg_node); | 
					
						
							|  |  |  | #endif /* THREADS_NO_SHARING */
 | 
					
						
							| 
									
										
										
										
											2009-08-05 05:48:00 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-06-17 17:14:16 +01:00
										 |  |  |   return; | 
					
						
							| 
									
										
										
										
											2001-04-09 19:54:03 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  | void showTable(tab_ent_ptr tab_ent, int show_mode, FILE *out) { | 
					
						
							| 
									
										
										
										
											2011-11-30 13:37:59 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   sg_node_ptr sg_node; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-25 18:38:46 +01:00
										 |  |  |   TrStat_out = out; | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   TrStat_show = show_mode; | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   TrStat_subgoals = 0; | 
					
						
							|  |  |  |   TrStat_sg_incomplete = 0; | 
					
						
							|  |  |  |   TrStat_sg_nodes = 1; | 
					
						
							|  |  |  |   TrStat_answers = 0; | 
					
						
							|  |  |  |   TrStat_answers_true = 0; | 
					
						
							|  |  |  |   TrStat_answers_no = 0; | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   TrStat_answers_pruned = 0; | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   TrStat_ans_nodes = 0; | 
					
						
							|  |  |  |   TrStat_gt_refs = 0; | 
					
						
							|  |  |  |   if (show_mode == SHOW_MODE_STATISTICS) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     fprintf(TrStat_out, "Table statistics for predicate '%s", | 
					
						
							|  |  |  |             AtomName(TabEnt_atom(tab_ent))); | 
					
						
							|  |  |  |   else /* SHOW_MODE_STRUCTURE */ | 
					
						
							|  |  |  |     fprintf(TrStat_out, "Table structure for predicate '%s", | 
					
						
							|  |  |  |             AtomName(TabEnt_atom(tab_ent))); | 
					
						
							| 
									
										
										
										
											2011-11-09 15:13:22 +00:00
										 |  |  | #ifdef MODE_DIRECTED_TABLING
 | 
					
						
							|  |  |  |   if (TabEnt_mode_directed(tab_ent)) { | 
					
						
							|  |  |  |     int i, *mode_directed = TabEnt_mode_directed(tab_ent); | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |     fprintf(TrStat_out, "("); | 
					
						
							| 
									
										
										
										
											2011-11-09 15:13:22 +00:00
										 |  |  |     for (i = 0; i < TabEnt_arity(tab_ent); i++) { | 
					
						
							|  |  |  |       int mode = MODE_DIRECTED_GET_MODE(mode_directed[i]); | 
					
						
							|  |  |  |       if (mode == MODE_DIRECTED_INDEX) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         fprintf(TrStat_out, "index"); | 
					
						
							| 
									
										
										
										
											2011-11-09 15:13:22 +00:00
										 |  |  |       } else if (mode == MODE_DIRECTED_MIN) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         fprintf(TrStat_out, "min"); | 
					
						
							| 
									
										
										
										
											2012-06-04 19:27:31 +01:00
										 |  |  |       } else if (mode == MODE_DIRECTED_MAX) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         fprintf(TrStat_out, "max"); | 
					
						
							| 
									
										
										
										
											2012-06-04 19:27:31 +01:00
										 |  |  |       } else if (mode == MODE_DIRECTED_ALL) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         fprintf(TrStat_out, "all"); | 
					
						
							| 
									
										
										
										
											2012-06-04 19:27:31 +01:00
										 |  |  |       } else if (mode == MODE_DIRECTED_SUM) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         fprintf(TrStat_out, "sum"); | 
					
						
							| 
									
										
										
										
											2012-06-04 19:27:31 +01:00
										 |  |  |       } else if (mode == MODE_DIRECTED_LAST) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         fprintf(TrStat_out, "last"); | 
					
						
							| 
									
										
										
										
											2012-06-04 19:27:31 +01:00
										 |  |  |       } else if (mode == MODE_DIRECTED_FIRST) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         fprintf(TrStat_out, "first"); | 
					
						
							| 
									
										
										
										
											2012-06-04 19:27:31 +01:00
										 |  |  |       } else | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "show_table: unknown mode"); | 
					
						
							| 
									
										
										
										
											2011-11-09 15:13:22 +00:00
										 |  |  |       if (i != MODE_DIRECTED_GET_ARG(mode_directed[i])) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         fprintf(TrStat_out, "(ARG%d)", | 
					
						
							|  |  |  |                 MODE_DIRECTED_GET_ARG(mode_directed[i]) + 1); | 
					
						
							| 
									
										
										
										
											2011-11-09 15:13:22 +00:00
										 |  |  |       if (i + 1 != TabEnt_arity(tab_ent)) | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         fprintf(TrStat_out, ","); | 
					
						
							| 
									
										
										
										
											2011-11-09 15:13:22 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |     fprintf(TrStat_out, ")'\n"); | 
					
						
							| 
									
										
										
										
											2011-11-09 15:13:22 +00:00
										 |  |  |   } else | 
					
						
							|  |  |  | #endif /* MODE_DIRECTED_TABLING */
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |     fprintf(TrStat_out, "/%d'\n", TabEnt_arity(tab_ent)); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   sg_node = get_subgoal_trie(tab_ent); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   if (sg_node) { | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |     if (TrNode_child(sg_node)) { | 
					
						
							|  |  |  |       if (TabEnt_arity(tab_ent)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         char *str = (char *)malloc(sizeof(char) * SHOW_TABLE_STR_ARRAY_SIZE); | 
					
						
							|  |  |  |         int *arity = (int *)malloc(sizeof(int) * SHOW_TABLE_ARITY_ARRAY_SIZE); | 
					
						
							|  |  |  |         arity[0] = 1; | 
					
						
							|  |  |  |         arity[1] = TabEnt_arity(tab_ent); | 
					
						
							|  |  |  |         int str_index = | 
					
						
							|  |  |  |             sprintf(str, "  ?- %s(", AtomName(TabEnt_atom(tab_ent))); | 
					
						
							|  |  |  |         traverse_subgoal_trie(TrNode_child(sg_node), str, str_index, arity, | 
					
						
							|  |  |  |                               TRAVERSE_MODE_NORMAL, | 
					
						
							|  |  |  |                               TRAVERSE_POSITION_FIRST PASS_REGS); | 
					
						
							|  |  |  |         free(str); | 
					
						
							|  |  |  |         free(arity); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |         sg_fr_ptr sg_fr = get_subgoal_frame(sg_node); | 
					
						
							|  |  |  |         if (sg_fr) { | 
					
						
							|  |  |  |           TrStat_subgoals++; | 
					
						
							|  |  |  |           SHOW_TABLE_STRUCTURE("  ?- %s.\n", AtomName(TabEnt_atom(tab_ent))); | 
					
						
							|  |  |  |           TrStat_ans_nodes++; | 
					
						
							|  |  |  |           if (SgFr_first_answer(sg_fr) == NULL) { | 
					
						
							|  |  |  |             if (SgFr_state(sg_fr) < complete) { | 
					
						
							|  |  |  |               TrStat_sg_incomplete++; | 
					
						
							|  |  |  |               SHOW_TABLE_STRUCTURE("    ---> INCOMPLETE\n"); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |               TrStat_answers_no++; | 
					
						
							|  |  |  |               SHOW_TABLE_STRUCTURE("    NO\n"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } else { /* SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr) */ | 
					
						
							|  |  |  |             TrStat_answers_true++; | 
					
						
							|  |  |  |             SHOW_TABLE_STRUCTURE("    TRUE\n"); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   if (TrStat_subgoals == 0) | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |     SHOW_TABLE_STRUCTURE("  EMPTY\n"); | 
					
						
							|  |  |  |   if (show_mode == SHOW_MODE_STATISTICS) { | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |     fprintf(TrStat_out, "  Subgoal trie structure\n"); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     fprintf(TrStat_out, "    Subgoals: %ld (%ld incomplete)\n", TrStat_subgoals, | 
					
						
							|  |  |  |             TrStat_sg_incomplete); | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |     fprintf(TrStat_out, "    Subgoal trie nodes: %ld\n", TrStat_sg_nodes); | 
					
						
							|  |  |  |     fprintf(TrStat_out, "  Answer trie structure(s)\n"); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #ifdef TABLING_INNER_CUTS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     fprintf(TrStat_out, "    Answers: %ld (%ld pruned)\n", TrStat_answers, | 
					
						
							|  |  |  |             TrStat_answers_pruned); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |     fprintf(TrStat_out, "    Answers: %ld\n", TrStat_answers); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  | #endif /* TABLING_INNER_CUTS */
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |     fprintf(TrStat_out, "    Answers 'TRUE': %ld\n", TrStat_answers_true); | 
					
						
							|  |  |  |     fprintf(TrStat_out, "    Answers 'NO': %ld\n", TrStat_answers_no); | 
					
						
							|  |  |  |     fprintf(TrStat_out, "    Answer trie nodes: %ld\n", TrStat_ans_nodes); | 
					
						
							|  |  |  |     fprintf(TrStat_out, "  Global trie references: %ld\n", TrStat_gt_refs); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  | void showGlobalTrie(int show_mode, FILE *out) { | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-25 18:38:46 +01:00
										 |  |  |   TrStat_out = out; | 
					
						
							| 
									
										
										
										
											2010-04-16 03:07:37 +01:00
										 |  |  |   TrStat_show = show_mode; | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   TrStat_gt_terms = 0; | 
					
						
							|  |  |  |   TrStat_gt_nodes = 1; | 
					
						
							|  |  |  |   TrStat_gt_refs = 0; | 
					
						
							|  |  |  |   if (show_mode == SHOW_MODE_STATISTICS) | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |     fprintf(TrStat_out, "Global trie statistics\n"); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   else /* SHOW_MODE_STRUCTURE */ | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |     fprintf(TrStat_out, "Global trie structure\n"); | 
					
						
							| 
									
										
										
										
											2011-05-10 11:47:18 +01:00
										 |  |  |   if (TrNode_child(GLOBAL_root_gt)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     char *str = (char *)malloc(sizeof(char) * SHOW_TABLE_STR_ARRAY_SIZE); | 
					
						
							|  |  |  |     int *arity = (int *)malloc(sizeof(int) * SHOW_TABLE_ARITY_ARRAY_SIZE); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |     arity[0] = 0; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     traverse_global_trie(TrNode_child(GLOBAL_root_gt), str, 0, arity, | 
					
						
							|  |  |  |                          TRAVERSE_MODE_NORMAL, | 
					
						
							|  |  |  |                          TRAVERSE_POSITION_FIRST PASS_REGS); | 
					
						
							| 
									
										
										
										
											2010-04-03 05:58:14 +01:00
										 |  |  |     free(str); | 
					
						
							|  |  |  |     free(arity); | 
					
						
							|  |  |  |   } else | 
					
						
							|  |  |  |     SHOW_TABLE_STRUCTURE("  EMPTY\n"); | 
					
						
							| 
									
										
										
										
											2010-04-16 03:07:37 +01:00
										 |  |  |   if (show_mode == SHOW_MODE_STATISTICS) { | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |     fprintf(TrStat_out, "  Terms: %ld\n", TrStat_gt_terms); | 
					
						
							|  |  |  |     fprintf(TrStat_out, "  Global trie nodes: %ld\n", TrStat_gt_nodes); | 
					
						
							|  |  |  |     fprintf(TrStat_out, "  Global trie auto references: %ld\n", TrStat_gt_refs); | 
					
						
							| 
									
										
										
										
											2010-04-16 03:07:37 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-09-27 02:31:31 +01:00
										 |  |  |   return; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2011-10-27 12:37:41 +02:00
										 |  |  | #endif /* TABLING */
 |