From 2e95faf4f7f916c6a76843400ec5f37936e8cb62 Mon Sep 17 00:00:00 2001 From: Theo Date: Sun, 18 Jul 2010 18:25:30 +0100 Subject: [PATCH 1/3] I added the dbtrie support :-) --- library/tries/base_dbtries.c | 444 +++++++++++++++++ library/tries/base_dbtries.h | 216 +++++++++ library/tries/core_dbtries.c | 893 +++++++++++++++++++++++++++++++++++ library/tries/core_dbtries.h | 229 +++++++++ 4 files changed, 1782 insertions(+) create mode 100644 library/tries/base_dbtries.c create mode 100644 library/tries/base_dbtries.h create mode 100644 library/tries/core_dbtries.c create mode 100644 library/tries/core_dbtries.h diff --git a/library/tries/base_dbtries.c b/library/tries/base_dbtries.c new file mode 100644 index 000000000..a82a159c7 --- /dev/null +++ b/library/tries/base_dbtries.c @@ -0,0 +1,444 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% $Date: 2010-06-30 17:05:24 +0200 (Wed, 30 Jun 2010) $ +% $Revision: 1 $ +% +% This file is part of YAP & ProbLog +% http://www.dcc.fc.up.pt/~vsc/Yap/index.html +% http://dtai.cs.kuleuven.be/problog +% +% ProbLog was developed at Katholieke Universiteit Leuven & +% University of Porto +% +% Copyright 2010 Katholieke Universiteit Leuven & University of Porto +% +% Main authors of this file: Mantadelis Theofrastos, Ricardo Rocha +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Artistic License 2.0 +% +% Copyright (c) 2000-2006, The Perl Foundation. +% +% Everyone is permitted to copy and distribute verbatim copies of this +% license document, but changing it is not allowed. Preamble +% +% This license establishes the terms under which a given free software +% Package may be copied, modified, distributed, and/or +% redistributed. The intent is that the Copyright Holder maintains some +% artistic control over the development of that Package while still +% keeping the Package available as open source and free software. +% +% You are always permitted to make arrangements wholly outside of this +% license directly with the Copyright Holder of a given Package. If the +% terms of this license do not permit the full use that you propose to +% make of the Package, you should contact the Copyright Holder and seek +% a different licensing arrangement. Definitions +% +% "Copyright Holder" means the individual(s) or organization(s) named in +% the copyright notice for the entire Package. +% +% "Contributor" means any party that has contributed code or other +% material to the Package, in accordance with the Copyright Holder's +% procedures. +% +% "You" and "your" means any person who would like to copy, distribute, +% or modify the Package. +% +% "Package" means the collection of files distributed by the Copyright +% Holder, and derivatives of that collection and/or of those files. A +% given Package may consist of either the Standard Version, or a +% Modified Version. +% +% "Distribute" means providing a copy of the Package or making it +% accessible to anyone else, or in the case of a company or +% organization, to others outside of your company or organization. +% +% "Distributor Fee" means any fee that you charge for Distributing this +% Package or providing support for this Package to another party. It +% does not mean licensing fees. +% +% "Standard Version" refers to the Package if it has not been modified, +% or has been modified only in ways explicitly requested by the +% Copyright Holder. +% +% "Modified Version" means the Package, if it has been changed, and such +% changes were not explicitly requested by the Copyright Holder. +% +% "Original License" means this Artistic License as Distributed with the +% Standard Version of the Package, in its current version or as it may +% be modified by The Perl Foundation in the future. +% +% "Source" form means the source code, documentation source, and +% configuration files for the Package. +% +% "Compiled" form means the compiled bytecode, object code, binary, or +% any other form resulting from mechanical transformation or translation +% of the Source form. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Permission for Use and Modification Without Distribution +% +% (1) You are permitted to use the Standard Version and create and use +% Modified Versions for any purpose without restriction, provided that +% you do not Distribute the Modified Version. +% +% Permissions for Redistribution of the Standard Version +% +% (2) You may Distribute verbatim copies of the Source form of the +% Standard Version of this Package in any medium without restriction, +% either gratis or for a Distributor Fee, provided that you duplicate +% all of the original copyright notices and associated disclaimers. At +% your discretion, such verbatim copies may or may not include a +% Compiled form of the Package. +% +% (3) You may apply any bug fixes, portability changes, and other +% modifications made available from the Copyright Holder. The resulting +% Package will still be considered the Standard Version, and as such +% will be subject to the Original License. +% +% Distribution of Modified Versions of the Package as Source +% +% (4) You may Distribute your Modified Version as Source (either gratis +% or for a Distributor Fee, and with or without a Compiled form of the +% Modified Version) provided that you clearly document how it differs +% from the Standard Version, including, but not limited to, documenting +% any non-standard features, executables, or modules, and provided that +% you do at least ONE of the following: +% +% (a) make the Modified Version available to the Copyright Holder of the +% Standard Version, under the Original License, so that the Copyright +% Holder may include your modifications in the Standard Version. (b) +% ensure that installation of your Modified Version does not prevent the +% user installing or running the Standard Version. In addition, the +% modified Version must bear a name that is different from the name of +% the Standard Version. (c) allow anyone who receives a copy of the +% Modified Version to make the Source form of the Modified Version +% available to others under (i) the Original License or (ii) a license +% that permits the licensee to freely copy, modify and redistribute the +% Modified Version using the same licensing terms that apply to the copy +% that the licensee received, and requires that the Source form of the +% Modified Version, and of any works derived from it, be made freely +% available in that license fees are prohibited but Distributor Fees are +% allowed. +% +% Distribution of Compiled Forms of the Standard Version or +% Modified Versions without the Source +% +% (5) You may Distribute Compiled forms of the Standard Version without +% the Source, provided that you include complete instructions on how to +% get the Source of the Standard Version. Such instructions must be +% valid at the time of your distribution. If these instructions, at any +% time while you are carrying out such distribution, become invalid, you +% must provide new instructions on demand or cease further +% distribution. If you provide valid instructions or cease distribution +% within thirty days after you become aware that the instructions are +% invalid, then you do not forfeit any of your rights under this +% license. +% +% (6) You may Distribute a Modified Version in Compiled form without the +% Source, provided that you comply with Section 4 with respect to the +% Source of the Modified Version. +% +% Aggregating or Linking the Package +% +% (7) You may aggregate the Package (either the Standard Version or +% Modified Version) with other packages and Distribute the resulting +% aggregation provided that you do not charge a licensing fee for the +% Package. Distributor Fees are permitted, and licensing fees for other +% components in the aggregation are permitted. The terms of this license +% apply to the use and Distribution of the Standard or Modified Versions +% as included in the aggregation. +% +% (8) You are permitted to link Modified and Standard Versions with +% other works, to embed the Package in a larger work of your own, or to +% build stand-alone binary or bytecode versions of applications that +% include the Package, and Distribute the result without restriction, +% provided the result does not expose a direct interface to the Package. +% +% Items That are Not Considered Part of a Modified Version +% +% (9) Works (including, but not limited to, modules and scripts) that +% merely extend or make use of the Package, do not, by themselves, cause +% the Package to be a Modified Version. In addition, such works are not +% considered parts of the Package itself, and are not subject to the +% terms of this license. +% +% General Provisions +% +% (10) Any use, modification, and distribution of the Standard or +% Modified Versions is governed by this Artistic License. By using, +% modifying or distributing the Package, you accept this license. Do not +% use, modify, or distribute the Package, if you do not accept this +% license. +% +% (11) If your Modified Version has been derived from a Modified Version +% made by someone other than you, you are nevertheless required to +% ensure that your Modified Version complies with the requirements of +% this license. +% +% (12) This license does not grant you the right to use any trademark, +% service mark, tradename, or logo of the Copyright Holder. +% +% (13) This license includes the non-exclusive, worldwide, +% free-of-charge patent license to make, have made, use, offer to sell, +% sell, import and otherwise transfer the Package with respect to any +% patent claims licensable by the Copyright Holder that are necessarily +% infringed by the Package. If you institute patent litigation +% (including a cross-claim or counterclaim) against any party alleging +% that the Package constitutes direct or contributory patent +% infringement, then this Artistic License to you shall terminate on the +% date that such litigation is filed. +% +% (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT +% HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED +% WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +% PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT +% PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT +% HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, +% INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE +% OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +#include + +/* -------------------------- */ +/* Local Procedures */ +/* -------------------------- */ + +static TrNode depth_reduction(TrEntry trie, TrNode depth_node, YAP_Int opt_level); +static TrNode breadth_reduction(TrEntry trie, TrNode breadth_node, YAP_Int opt_level); +inline int compare_label_nodes(TrData data1, TrData data2); +inline void move_after(TrData data_source, TrData data_dest); +inline void move_last_data_after(TrData moveto_data); +inline void set_depth_breadth_reduction_current_data(TrData data); + + +/* -------------------------- */ +/* Local Variables */ +/* -------------------------- */ + +static TrData CURRENT_DEPTH_BREADTH_DATA; + + +/* -------------------------- */ +/* API */ +/* -------------------------- */ + +inline +YAP_Term trie_depth_breadth(TrEntry trie, TrEntry db_trie, YAP_Int opt_level, YAP_Int start_counter, YAP_Int *end_counter) { + TrNode depth_node, breadth_node, nested_trie; + core_set_label_counter(start_counter); + CURRENT_TRIE = db_trie; + core_set_trie_db_return_term(YAP_MkAtomTerm(YAP_LookupAtom("false"))); + core_initialize_depth_breadth_trie(TrEntry_trie(db_trie), &depth_node, &breadth_node); + set_depth_breadth_reduction_current_data(NULL); + while (TrNode_child(TrEntry_trie(trie))) { + nested_trie = depth_reduction(trie, depth_node, opt_level); + if (nested_trie) { + set_depth_breadth_reduction_current_data(get_data_from_trie_node(nested_trie)); + core_finalize_depth_breadth_trie(depth_node, breadth_node); + *end_counter = core_get_label_counter(); + return YAP_MkApplTerm((YAP_Functor)(~ApplTag & TrNode_entry(TrNode_parent(nested_trie))), 1, &TrNode_entry(nested_trie)); + } + nested_trie = breadth_reduction(trie, breadth_node, opt_level); + if (nested_trie) { + set_depth_breadth_reduction_current_data(get_data_from_trie_node(nested_trie)); + core_finalize_depth_breadth_trie(depth_node, breadth_node); + *end_counter = core_get_label_counter(); + return YAP_MkApplTerm((YAP_Functor)(~ApplTag & TrNode_entry(TrNode_parent(nested_trie))), 1, &TrNode_entry(nested_trie)); + } + } + core_finalize_depth_breadth_trie(depth_node, breadth_node); + *end_counter = core_get_label_counter(); + return core_get_trie_db_return_term(); +} + + +inline +YAP_Int trie_get_db_opt_level_count(YAP_Int opt_level) { + return core_db_trie_get_optimization_level_count(opt_level); +} + + +inline +TrData trie_get_depth_breadth_reduction_current_data(void) { + return CURRENT_DEPTH_BREADTH_DATA; +} + + +inline +void trie_replace_nested_trie(TrEntry trie, YAP_Int nested_trie_id, YAP_Term new_term) { + core_depth_breadth_trie_replace_nested_trie(TrNode_child(TrEntry_trie(trie)), nested_trie_id, new_term); + return; +} + + +inline +YAP_Int trie_get_db_opt_min_prefix(void) { + return core_get_trie_db_opt_min_prefix(); +} + + +inline +void trie_set_db_opt_min_prefix(YAP_Int min_prefix) { + core_set_trie_db_opt_min_prefix(min_prefix); + return; +} + + +/* -------------------------- */ +/* Local Procedures */ +/* -------------------------- */ + + +inline +void set_depth_breadth_reduction_current_data(TrData data) { + CURRENT_DEPTH_BREADTH_DATA = data; + return; +} + + +static +TrNode depth_reduction(TrEntry trie, TrNode depth_node, YAP_Int opt_level) { + TrNode node; + TrData stop_data, new_data, data = NULL; + + stop_data = TrData_previous(TrEntry_first_data(trie)); + data = TrEntry_traverse_data(trie) = TrEntry_last_data(trie); + while (data != stop_data) { +// printf("hi0\n"); + node = core_depth_reduction(TRIE_ENGINE, TrData_leaf(data), depth_node, opt_level, &trie_data_construct, &trie_data_destruct, &trie_data_copy, &trie_data_order_correction); +// printf("bye0\n"); + if (node && IS_FUNCTOR_NODE(TrNode_parent(node)) && (strcmp(YAP_AtomName(YAP_NameOfFunctor((YAP_Functor)(~ApplTag & TrNode_entry(TrNode_parent(node))))), NESTED_TRIE_TERM) == 0)) { + //nested trie stop procedure return nested trie node + return node; + } + if (node) { + new_trie_data(new_data, trie, node); + PUT_DATA_IN_LEAF_TRIE_NODE(node, new_data); + } + if (data == TrEntry_traverse_data(trie)) { + data = TrData_previous(data); + TrEntry_traverse_data(trie) = data; + } else + data = TrEntry_traverse_data(trie); + } + return NULL; +} + + +static +TrNode breadth_reduction(TrEntry trie, TrNode breadth_node, YAP_Int opt_level) { + TrNode node; + TrData stop_data, new_data, data = NULL; + + stop_data = TrData_previous(TrEntry_first_data(trie)); + data = TrEntry_traverse_data(trie) = TrEntry_last_data(trie); + while ((data != stop_data) && (data != NULL)) { +/* printf("hi1\n");*/ + node = core_breadth_reduction(TRIE_ENGINE, TrData_leaf(data), breadth_node, opt_level, &trie_data_construct, &trie_data_destruct, &trie_data_copy, &trie_data_order_correction); +// printf("bye1\n"); + if (node && IS_FUNCTOR_NODE(TrNode_parent(node)) && (strcmp(YAP_AtomName(YAP_NameOfFunctor((YAP_Functor)(~ApplTag & TrNode_entry(TrNode_parent(node))))), NESTED_TRIE_TERM) == 0)) { + //nested trie stop procedure return nested trie node + return node; + } + if (node) { + new_trie_data(new_data, trie, node); + PUT_DATA_IN_LEAF_TRIE_NODE(node, new_data); + } + if (data == TrEntry_traverse_data(trie)) { + data = TrData_previous(data); + TrEntry_traverse_data(trie) = data; + } else + data = TrEntry_traverse_data(trie); + } + return NULL; +} + + +inline +void move_last_data_after(TrData moveto_data) { + TrEntry trie = CURRENT_TRIE; + TrData last_data = TrEntry_last_data(trie); + TrEntry_last_data(trie) = TrData_previous(last_data); + TrData_next(TrData_previous(last_data)) = TrData_next(last_data); + if (moveto_data == TrData_previous(TrEntry_first_data(trie))) { + TrData_next(last_data) = TrEntry_first_data(trie); + TrEntry_first_data(trie) = last_data; + } else { + TrData_next(last_data) = TrData_next(moveto_data); + TrData_next(moveto_data) = last_data; + } + TrData_previous(last_data) = moveto_data; + TrData_previous(TrData_next(last_data)) = last_data; + return; +} + + +inline +void move_after(TrData data_source, TrData data_dest) { + TrEntry trie = CURRENT_TRIE; + if (data_source == TrEntry_first_data(trie)) + TrEntry_first_data(trie) = TrData_next(data_source); + else + TrData_next(TrData_previous(data_source)) = TrData_next(data_source); + if (data_source == TrEntry_last_data(trie)) + TrEntry_last_data(trie) = TrData_previous(data_source); + else + TrData_previous(TrData_next(data_source)) = TrData_previous(data_source); + + if (data_dest == TrData_previous(TrEntry_first_data(trie))) { + TrData_next(data_source) = TrEntry_first_data(trie); + TrData_previous(TrEntry_first_data(trie)) = data_source; + TrEntry_first_data(trie) = data_source; + } else { + TrData_next(data_source) = TrData_next(data_dest); + if (data_dest == TrEntry_last_data(trie)) + TrEntry_last_data(trie) = data_source; + else + TrData_previous(TrData_next(data_dest)) = data_source; + TrData_next(data_dest) = data_source; + } + TrData_previous(data_source) = data_dest; + return; +} + + +inline +void trie_data_order_correction(void) { + TrEntry trie = CURRENT_TRIE; + TrData inserted_data = TrEntry_last_data(trie); + TrData moved_data = TrData_previous(inserted_data); + TrData moveto_data = TrData_previous(moved_data); + + while((moveto_data != TrData_previous(TrEntry_first_data(trie))) && (compare_label_nodes(moveto_data, inserted_data) == 1)) { + if (compare_label_nodes(moveto_data, moved_data) == 2) + moved_data = moveto_data; + moveto_data = TrData_previous(moveto_data); + } + move_last_data_after(moveto_data); + + do { + moveto_data = TrData_next(inserted_data); + while(compare_label_nodes(moveto_data, moved_data) == 2) + moveto_data = TrData_next(moveto_data); + inserted_data = moved_data; + moved_data = TrData_next(moved_data); + if (moved_data != moveto_data) + move_after(inserted_data, TrData_previous(moveto_data)); + } while(moved_data); + return; +} + + +inline +int compare_label_nodes(TrData data1, TrData data2) { + YAP_Term t1 = TrNode_entry(TrData_leaf(data1)), t2 = TrNode_entry(TrData_leaf(data2)); + YAP_Int i1 = atol(YAP_AtomName(YAP_AtomOfTerm(t1)) + 1), i2 = atol(YAP_AtomName(YAP_AtomOfTerm(t2)) + 1); + if (i1 == i2) return 0; + if (i1 > i2) return 1; + return 2; +} diff --git a/library/tries/base_dbtries.h b/library/tries/base_dbtries.h new file mode 100644 index 000000000..efb082470 --- /dev/null +++ b/library/tries/base_dbtries.h @@ -0,0 +1,216 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% $Date: 2010-06-30 17:05:24 +0200 (Wed, 30 Jun 2010) $ +% $Revision: 1 $ +% +% This file is part of YAP & ProbLog +% http://www.dcc.fc.up.pt/~vsc/Yap/index.html +% http://dtai.cs.kuleuven.be/problog +% +% ProbLog was developed at Katholieke Universiteit Leuven & +% University of Porto +% +% Copyright 2010 Katholieke Universiteit Leuven & University of Porto +% +% Main authors of this file: Mantadelis Theofrastos, Ricardo Rocha +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Artistic License 2.0 +% +% Copyright (c) 2000-2006, The Perl Foundation. +% +% Everyone is permitted to copy and distribute verbatim copies of this +% license document, but changing it is not allowed. Preamble +% +% This license establishes the terms under which a given free software +% Package may be copied, modified, distributed, and/or +% redistributed. The intent is that the Copyright Holder maintains some +% artistic control over the development of that Package while still +% keeping the Package available as open source and free software. +% +% You are always permitted to make arrangements wholly outside of this +% license directly with the Copyright Holder of a given Package. If the +% terms of this license do not permit the full use that you propose to +% make of the Package, you should contact the Copyright Holder and seek +% a different licensing arrangement. Definitions +% +% "Copyright Holder" means the individual(s) or organization(s) named in +% the copyright notice for the entire Package. +% +% "Contributor" means any party that has contributed code or other +% material to the Package, in accordance with the Copyright Holder's +% procedures. +% +% "You" and "your" means any person who would like to copy, distribute, +% or modify the Package. +% +% "Package" means the collection of files distributed by the Copyright +% Holder, and derivatives of that collection and/or of those files. A +% given Package may consist of either the Standard Version, or a +% Modified Version. +% +% "Distribute" means providing a copy of the Package or making it +% accessible to anyone else, or in the case of a company or +% organization, to others outside of your company or organization. +% +% "Distributor Fee" means any fee that you charge for Distributing this +% Package or providing support for this Package to another party. It +% does not mean licensing fees. +% +% "Standard Version" refers to the Package if it has not been modified, +% or has been modified only in ways explicitly requested by the +% Copyright Holder. +% +% "Modified Version" means the Package, if it has been changed, and such +% changes were not explicitly requested by the Copyright Holder. +% +% "Original License" means this Artistic License as Distributed with the +% Standard Version of the Package, in its current version or as it may +% be modified by The Perl Foundation in the future. +% +% "Source" form means the source code, documentation source, and +% configuration files for the Package. +% +% "Compiled" form means the compiled bytecode, object code, binary, or +% any other form resulting from mechanical transformation or translation +% of the Source form. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Permission for Use and Modification Without Distribution +% +% (1) You are permitted to use the Standard Version and create and use +% Modified Versions for any purpose without restriction, provided that +% you do not Distribute the Modified Version. +% +% Permissions for Redistribution of the Standard Version +% +% (2) You may Distribute verbatim copies of the Source form of the +% Standard Version of this Package in any medium without restriction, +% either gratis or for a Distributor Fee, provided that you duplicate +% all of the original copyright notices and associated disclaimers. At +% your discretion, such verbatim copies may or may not include a +% Compiled form of the Package. +% +% (3) You may apply any bug fixes, portability changes, and other +% modifications made available from the Copyright Holder. The resulting +% Package will still be considered the Standard Version, and as such +% will be subject to the Original License. +% +% Distribution of Modified Versions of the Package as Source +% +% (4) You may Distribute your Modified Version as Source (either gratis +% or for a Distributor Fee, and with or without a Compiled form of the +% Modified Version) provided that you clearly document how it differs +% from the Standard Version, including, but not limited to, documenting +% any non-standard features, executables, or modules, and provided that +% you do at least ONE of the following: +% +% (a) make the Modified Version available to the Copyright Holder of the +% Standard Version, under the Original License, so that the Copyright +% Holder may include your modifications in the Standard Version. (b) +% ensure that installation of your Modified Version does not prevent the +% user installing or running the Standard Version. In addition, the +% modified Version must bear a name that is different from the name of +% the Standard Version. (c) allow anyone who receives a copy of the +% Modified Version to make the Source form of the Modified Version +% available to others under (i) the Original License or (ii) a license +% that permits the licensee to freely copy, modify and redistribute the +% Modified Version using the same licensing terms that apply to the copy +% that the licensee received, and requires that the Source form of the +% Modified Version, and of any works derived from it, be made freely +% available in that license fees are prohibited but Distributor Fees are +% allowed. +% +% Distribution of Compiled Forms of the Standard Version or +% Modified Versions without the Source +% +% (5) You may Distribute Compiled forms of the Standard Version without +% the Source, provided that you include complete instructions on how to +% get the Source of the Standard Version. Such instructions must be +% valid at the time of your distribution. If these instructions, at any +% time while you are carrying out such distribution, become invalid, you +% must provide new instructions on demand or cease further +% distribution. If you provide valid instructions or cease distribution +% within thirty days after you become aware that the instructions are +% invalid, then you do not forfeit any of your rights under this +% license. +% +% (6) You may Distribute a Modified Version in Compiled form without the +% Source, provided that you comply with Section 4 with respect to the +% Source of the Modified Version. +% +% Aggregating or Linking the Package +% +% (7) You may aggregate the Package (either the Standard Version or +% Modified Version) with other packages and Distribute the resulting +% aggregation provided that you do not charge a licensing fee for the +% Package. Distributor Fees are permitted, and licensing fees for other +% components in the aggregation are permitted. The terms of this license +% apply to the use and Distribution of the Standard or Modified Versions +% as included in the aggregation. +% +% (8) You are permitted to link Modified and Standard Versions with +% other works, to embed the Package in a larger work of your own, or to +% build stand-alone binary or bytecode versions of applications that +% include the Package, and Distribute the result without restriction, +% provided the result does not expose a direct interface to the Package. +% +% Items That are Not Considered Part of a Modified Version +% +% (9) Works (including, but not limited to, modules and scripts) that +% merely extend or make use of the Package, do not, by themselves, cause +% the Package to be a Modified Version. In addition, such works are not +% considered parts of the Package itself, and are not subject to the +% terms of this license. +% +% General Provisions +% +% (10) Any use, modification, and distribution of the Standard or +% Modified Versions is governed by this Artistic License. By using, +% modifying or distributing the Package, you accept this license. Do not +% use, modify, or distribute the Package, if you do not accept this +% license. +% +% (11) If your Modified Version has been derived from a Modified Version +% made by someone other than you, you are nevertheless required to +% ensure that your Modified Version complies with the requirements of +% this license. +% +% (12) This license does not grant you the right to use any trademark, +% service mark, tradename, or logo of the Copyright Holder. +% +% (13) This license includes the non-exclusive, worldwide, +% free-of-charge patent license to make, have made, use, offer to sell, +% sell, import and otherwise transfer the Package with respect to any +% patent claims licensable by the Copyright Holder that are necessarily +% infringed by the Package. If you institute patent litigation +% (including a cross-claim or counterclaim) against any party alleging +% that the Package constitutes direct or contributory patent +% infringement, then this Artistic License to you shall terminate on the +% date that such litigation is filed. +% +% (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT +% HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED +% WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +% PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT +% PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT +% HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, +% INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE +% OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + + +/* --------------------------- */ +/* API */ +/* --------------------------- */ + +inline YAP_Term trie_depth_breadth(TrEntry trie, TrEntry db_trie, YAP_Int opt_level, YAP_Int start_counter, YAP_Int *end_counter); +inline void trie_data_order_correction(void); +inline TrData trie_get_depth_breadth_reduction_current_data(void); +inline YAP_Int trie_get_db_opt_level_count(YAP_Int opt_level); +inline void trie_replace_nested_trie(TrEntry trie, YAP_Int nested_trie_id, YAP_Term new_term); +inline YAP_Int trie_get_db_opt_min_prefix(void); +inline void trie_set_db_opt_min_prefix(YAP_Int min_prefix); diff --git a/library/tries/core_dbtries.c b/library/tries/core_dbtries.c new file mode 100644 index 000000000..682a49cd4 --- /dev/null +++ b/library/tries/core_dbtries.c @@ -0,0 +1,893 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% $Date: 2010-06-30 17:05:24 +0200 (Wed, 30 Jun 2010) $ +% $Revision: 1 $ +% +% This file is part of YAP & ProbLog +% http://www.dcc.fc.up.pt/~vsc/Yap/index.html +% http://dtai.cs.kuleuven.be/problog +% +% ProbLog was developed at Katholieke Universiteit Leuven & +% University of Porto +% +% Copyright 2010 Katholieke Universiteit Leuven & University of Porto +% +% Main authors of this file: Mantadelis Theofrastos, Ricardo Rocha +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Artistic License 2.0 +% +% Copyright (c) 2000-2006, The Perl Foundation. +% +% Everyone is permitted to copy and distribute verbatim copies of this +% license document, but changing it is not allowed. Preamble +% +% This license establishes the terms under which a given free software +% Package may be copied, modified, distributed, and/or +% redistributed. The intent is that the Copyright Holder maintains some +% artistic control over the development of that Package while still +% keeping the Package available as open source and free software. +% +% You are always permitted to make arrangements wholly outside of this +% license directly with the Copyright Holder of a given Package. If the +% terms of this license do not permit the full use that you propose to +% make of the Package, you should contact the Copyright Holder and seek +% a different licensing arrangement. Definitions +% +% "Copyright Holder" means the individual(s) or organization(s) named in +% the copyright notice for the entire Package. +% +% "Contributor" means any party that has contributed code or other +% material to the Package, in accordance with the Copyright Holder's +% procedures. +% +% "You" and "your" means any person who would like to copy, distribute, +% or modify the Package. +% +% "Package" means the collection of files distributed by the Copyright +% Holder, and derivatives of that collection and/or of those files. A +% given Package may consist of either the Standard Version, or a +% Modified Version. +% +% "Distribute" means providing a copy of the Package or making it +% accessible to anyone else, or in the case of a company or +% organization, to others outside of your company or organization. +% +% "Distributor Fee" means any fee that you charge for Distributing this +% Package or providing support for this Package to another party. It +% does not mean licensing fees. +% +% "Standard Version" refers to the Package if it has not been modified, +% or has been modified only in ways explicitly requested by the +% Copyright Holder. +% +% "Modified Version" means the Package, if it has been changed, and such +% changes were not explicitly requested by the Copyright Holder. +% +% "Original License" means this Artistic License as Distributed with the +% Standard Version of the Package, in its current version or as it may +% be modified by The Perl Foundation in the future. +% +% "Source" form means the source code, documentation source, and +% configuration files for the Package. +% +% "Compiled" form means the compiled bytecode, object code, binary, or +% any other form resulting from mechanical transformation or translation +% of the Source form. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Permission for Use and Modification Without Distribution +% +% (1) You are permitted to use the Standard Version and create and use +% Modified Versions for any purpose without restriction, provided that +% you do not Distribute the Modified Version. +% +% Permissions for Redistribution of the Standard Version +% +% (2) You may Distribute verbatim copies of the Source form of the +% Standard Version of this Package in any medium without restriction, +% either gratis or for a Distributor Fee, provided that you duplicate +% all of the original copyright notices and associated disclaimers. At +% your discretion, such verbatim copies may or may not include a +% Compiled form of the Package. +% +% (3) You may apply any bug fixes, portability changes, and other +% modifications made available from the Copyright Holder. The resulting +% Package will still be considered the Standard Version, and as such +% will be subject to the Original License. +% +% Distribution of Modified Versions of the Package as Source +% +% (4) You may Distribute your Modified Version as Source (either gratis +% or for a Distributor Fee, and with or without a Compiled form of the +% Modified Version) provided that you clearly document how it differs +% from the Standard Version, including, but not limited to, documenting +% any non-standard features, executables, or modules, and provided that +% you do at least ONE of the following: +% +% (a) make the Modified Version available to the Copyright Holder of the +% Standard Version, under the Original License, so that the Copyright +% Holder may include your modifications in the Standard Version. (b) +% ensure that installation of your Modified Version does not prevent the +% user installing or running the Standard Version. In addition, the +% modified Version must bear a name that is different from the name of +% the Standard Version. (c) allow anyone who receives a copy of the +% Modified Version to make the Source form of the Modified Version +% available to others under (i) the Original License or (ii) a license +% that permits the licensee to freely copy, modify and redistribute the +% Modified Version using the same licensing terms that apply to the copy +% that the licensee received, and requires that the Source form of the +% Modified Version, and of any works derived from it, be made freely +% available in that license fees are prohibited but Distributor Fees are +% allowed. +% +% Distribution of Compiled Forms of the Standard Version or +% Modified Versions without the Source +% +% (5) You may Distribute Compiled forms of the Standard Version without +% the Source, provided that you include complete instructions on how to +% get the Source of the Standard Version. Such instructions must be +% valid at the time of your distribution. If these instructions, at any +% time while you are carrying out such distribution, become invalid, you +% must provide new instructions on demand or cease further +% distribution. If you provide valid instructions or cease distribution +% within thirty days after you become aware that the instructions are +% invalid, then you do not forfeit any of your rights under this +% license. +% +% (6) You may Distribute a Modified Version in Compiled form without the +% Source, provided that you comply with Section 4 with respect to the +% Source of the Modified Version. +% +% Aggregating or Linking the Package +% +% (7) You may aggregate the Package (either the Standard Version or +% Modified Version) with other packages and Distribute the resulting +% aggregation provided that you do not charge a licensing fee for the +% Package. Distributor Fees are permitted, and licensing fees for other +% components in the aggregation are permitted. The terms of this license +% apply to the use and Distribution of the Standard or Modified Versions +% as included in the aggregation. +% +% (8) You are permitted to link Modified and Standard Versions with +% other works, to embed the Package in a larger work of your own, or to +% build stand-alone binary or bytecode versions of applications that +% include the Package, and Distribute the result without restriction, +% provided the result does not expose a direct interface to the Package. +% +% Items That are Not Considered Part of a Modified Version +% +% (9) Works (including, but not limited to, modules and scripts) that +% merely extend or make use of the Package, do not, by themselves, cause +% the Package to be a Modified Version. In addition, such works are not +% considered parts of the Package itself, and are not subject to the +% terms of this license. +% +% General Provisions +% +% (10) Any use, modification, and distribution of the Standard or +% Modified Versions is governed by this Artistic License. By using, +% modifying or distributing the Package, you accept this license. Do not +% use, modify, or distribute the Package, if you do not accept this +% license. +% +% (11) If your Modified Version has been derived from a Modified Version +% made by someone other than you, you are nevertheless required to +% ensure that your Modified Version complies with the requirements of +% this license. +% +% (12) This license does not grant you the right to use any trademark, +% service mark, tradename, or logo of the Copyright Holder. +% +% (13) This license includes the non-exclusive, worldwide, +% free-of-charge patent license to make, have made, use, offer to sell, +% sell, import and otherwise transfer the Package with respect to any +% patent claims licensable by the Copyright Holder that are necessarily +% infringed by the Package. If you institute patent litigation +% (including a cross-claim or counterclaim) against any party alleging +% that the Package constitutes direct or contributory patent +% infringement, then this Artistic License to you shall terminate on the +% date that such litigation is filed. +% +% (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT +% HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED +% WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +% PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT +% PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT +% HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, +% INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE +% OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + +/* -------------------------- */ +/* Local Procedures */ +/* -------------------------- */ + +inline void displaynode(TrNode node); +inline int traverse_get_counter(TrNode node); +inline YAP_Term generate_label(YAP_Int Index); +inline YAP_Term update_depth_breadth_trie(TrEngine engine, TrNode root, YAP_Int opt_level, void (*construct_function)(TrNode), void (*destruct_function)(TrNode), void (*copy_function)(TrNode, TrNode), void (*correct_order_function)(void)); +inline YAP_Term get_return_node_term(TrNode node); +inline void traverse_and_replace_nested_trie(TrNode node, YAP_Int nested_trie_id, YAP_Term new_term); +inline TrNode replace_nested_trie(TrNode node, TrNode child, YAP_Term new_term); + + +/* -------------------------- */ +/* Local Variables */ +/* -------------------------- */ + +static YAP_Int LABEL_COUNTER; +static YAP_Term TRIE_DEPTH_BREADTH_RETURN_TERM; +static YAP_Int TRIE_DEPTH_BREADTH_MIN_PREFIX = 2; +static YAP_Int TRIE_DEPTH_BREADTH_OPT_COUNT[3]; + + +/* -------------------------- */ +/* depth-breadth Trie */ +/* -------------------------- */ + +inline +YAP_Int core_get_trie_db_opt_min_prefix(void) { + return TRIE_DEPTH_BREADTH_MIN_PREFIX; +} + + +inline +void core_set_trie_db_opt_min_prefix(YAP_Int min_prefix) { + TRIE_DEPTH_BREADTH_MIN_PREFIX = min_prefix; + return; +} + + +inline +void core_depth_breadth_trie_replace_nested_trie(TrNode node, YAP_Int nested_trie_id, YAP_Term new_term) { + traverse_and_replace_nested_trie(node, nested_trie_id, new_term); + return; +} +inline +void displaynode(TrNode node) { + if (node != NULL) { +/* printf("hi\n"); + if (IS_HASH_NODE(node)) + {printf("1\n");} else {printf("2\n");} + printf("bye\n");*/ + if (IS_HASH_NODE(node)) + printf("HASH n%i, b%i, p%li\n", TrHash_num_nodes((TrHash) node), TrHash_num_buckets((TrHash) node), (long) node); + else if (TrNode_entry(node) == PairInitTag) + printf("PairInitTag\n"); + else if (TrNode_entry(node) == PairEndTag) + printf("PairEndTag\n"); + else if (IS_FUNCTOR_NODE(node)) + {printf("2\n"); + printf("FUNCTOR %s\n", YAP_AtomName(YAP_NameOfFunctor((YAP_Functor)( ~ApplTag & TrNode_entry(node)))));} + else if (YAP_IsIntTerm(TrNode_entry(node))) + {printf("3\n"); + printf("%ld\n", YAP_IntOfTerm(TrNode_entry(node)));} + else if (YAP_IsAtomTerm(TrNode_entry(node))) + {printf("4\n"); + printf("%s\n", YAP_AtomName(YAP_AtomOfTerm(TrNode_entry(node))));} + else + printf("What?\n"); + } else + printf("null\n"); + return; +} + + +inline +void traverse_and_replace_nested_trie(TrNode node, YAP_Int nested_trie_id, YAP_Term new_term) { + TrNode child, temp; + if (TrNode_entry(node) == PairEndTag) { + if (TrNode_next(node)) + traverse_and_replace_nested_trie(TrNode_next(node), nested_trie_id, new_term); + return; + } else if (IS_HASH_NODE(node)) { + abort(); + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) node; + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + do { + if ((node = *--bucket)) { + do { + traverse_and_replace_nested_trie(node, nested_trie_id, new_term); + node = TrNode_next(node); + } while(node); + } + } while (bucket != first_bucket); + } else { + if (IS_FUNCTOR_NODE(node)) { + YAP_Functor f = (YAP_Functor) (~ApplTag & TrNode_entry(node)); + YAP_Int arity = YAP_ArityOfFunctor(f); + if (arity == 1 && strcmp(YAP_AtomName(YAP_NameOfFunctor(f)), NESTED_TRIE_TERM) == 0) { + child = TrNode_child(node); + if (IS_HASH_NODE(child)) { + abort(); + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) child; + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + do { + if ((child = *--bucket)) { + do { + if (YAP_IntOfTerm(TrNode_entry(child)) == nested_trie_id) { + temp = TrNode_previous(node); + node = replace_nested_trie(node, child, new_term); + if (temp) { + temp = TrNode_next(node); + if (temp) + node = temp; + } else { + traverse_and_replace_nested_trie(TrNode_child(node), nested_trie_id, new_term); + return; + } + } + child = TrNode_next(child); + } while(child); + } + } while (bucket != first_bucket); + + } else { + do { + if (YAP_IntOfTerm(TrNode_entry(child)) == nested_trie_id) { + temp = TrNode_next(node); + node = replace_nested_trie(node, child, new_term); + traverse_and_replace_nested_trie(TrNode_child(node), nested_trie_id, new_term); + if(temp) + traverse_and_replace_nested_trie(temp, nested_trie_id, new_term); + return; + } + child = TrNode_next(child); + } while(child); + } + } + } + traverse_and_replace_nested_trie(TrNode_child(node), nested_trie_id, new_term); + if (TrNode_next(node)) + traverse_and_replace_nested_trie(TrNode_next(node), nested_trie_id, new_term); + } + return; +} + +/* fixmeeee */ +inline +TrNode replace_nested_trie(TrNode node, TrNode child, YAP_Term new_term) { + TrNode newnode, temp, newnodef = NULL; + if (YAP_IsApplTerm(new_term)) { + YAP_Term new_term_functor = ApplTag | ((YAP_Term) YAP_FunctorOfTerm(new_term)); + YAP_Int arity = YAP_ArityOfFunctor(YAP_FunctorOfTerm(new_term)); + if (arity != 1) abort(); + YAP_Term new_term_arg = YAP_ArgOfTerm(1, new_term); + temp = TrNode_child(TrNode_parent(node)); + while (temp) { + if (TrNode_entry(temp) == new_term_functor) { + printf("Warning - non tested code, please report the example to Theo to test it!\n"); + newnodef = temp; + temp = NULL; + } else { + temp = TrNode_next(temp); + } + } + if (newnodef == NULL) { + new_trie_node(newnodef, new_term_functor, TrNode_parent(node), NULL, TrNode_child(TrNode_parent(node)), NULL); + TrNode_previous(TrNode_child(TrNode_parent(node))) = newnodef; + TrNode_child(TrNode_parent(node)) = newnodef; + } + new_trie_node(newnode, new_term_arg, newnodef, TrNode_child(child), TrNode_child(newnodef), NULL); + if (TrNode_child(newnodef)) + TrNode_previous(TrNode_child(newnodef)) = newnode; + TrNode_child(newnodef) = newnode; + } else { + new_trie_node(newnode, new_term, TrNode_parent(node), TrNode_child(child), TrNode_child(TrNode_parent(node)), NULL); + TrNode_previous(TrNode_child(TrNode_parent(node))) = newnode; + TrNode_child(TrNode_parent(node)) = newnode; + } + temp = TrNode_child(child); + if (IS_HASH_NODE(temp)) { + abort(); + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) temp; + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + do { + if ((temp = *--bucket)) { + do { + TrNode_parent(temp) = newnode; + temp = TrNode_next(temp); + } while(temp); + } + } while (bucket != first_bucket); + } else { + while (temp) { + TrNode_parent(temp) = newnode; + temp = TrNode_next(temp); + } + } + TrNode_child(child) = NULL; + remove_entry(child); + return newnode; +} + + +inline +YAP_Term core_get_trie_db_return_term(void) { + return TRIE_DEPTH_BREADTH_RETURN_TERM; +} + + +inline +void core_set_trie_db_return_term(YAP_Term return_value){ + TRIE_DEPTH_BREADTH_RETURN_TERM = return_value; + return; +} + + +inline +void core_set_label_counter(YAP_Int value) { + LABEL_COUNTER = value; // Initialize the counter + return; +} + +inline +YAP_Int core_get_label_counter(void) { + return LABEL_COUNTER; +} + +inline +void core_initialize_depth_breadth_trie(TrNode node, TrNode *depth_node, TrNode *breadth_node) { + TrNode root = node; + YAP_Functor f; + f = YAP_MkFunctor(YAP_LookupAtom("depth"),2); + node = trie_node_check_insert(root, ApplTag | ((YAP_Term) f)); + *depth_node = trie_node_check_insert(node, PairInitTag); + f = YAP_MkFunctor(YAP_LookupAtom("breadth"),2); + node = trie_node_check_insert(root, ApplTag | ((YAP_Term) f)); + *breadth_node = trie_node_check_insert(node, PairInitTag); + TRIE_DEPTH_BREADTH_OPT_COUNT[0] = 0; + TRIE_DEPTH_BREADTH_OPT_COUNT[1] = 0; + TRIE_DEPTH_BREADTH_OPT_COUNT[2] = 0; + return; +} + + +inline +void core_finalize_depth_breadth_trie(TrNode depth_node, TrNode breadth_node) { + depth_node = trie_node_check_insert(depth_node, YAP_MkIntTerm(1)); + depth_node = trie_node_check_insert(depth_node, PairEndTag); + depth_node = trie_node_check_insert(depth_node, YAP_MkIntTerm(1)); + remove_entry(depth_node); + breadth_node = trie_node_check_insert(breadth_node, YAP_MkIntTerm(1)); + breadth_node = trie_node_check_insert(breadth_node, PairEndTag); + breadth_node = trie_node_check_insert(breadth_node, YAP_MkIntTerm(1)); + remove_entry(breadth_node); + return; +} + + +inline +TrNode core_depth_reduction(TrEngine engine, TrNode node, TrNode depth_node, YAP_Int opt_level, void (*construct_function)(TrNode), void (*destruct_function)(TrNode), void (*copy_function)(TrNode, TrNode), void (*correct_order_function)(void)) { + TrNode leaf = node; + YAP_Term t, *stack_top; + int count = -1; + /* collect depth nodes */ + stack_args_base = stack_args = AUXILIARY_TERM_STACK; + stack_top = AUXILIARY_TERM_STACK + CURRENT_AUXILIARY_TERM_STACK_SIZE - 1; + do { + node = TrNode_parent(node); + if (TrNode_entry(node) == PairInitTag) { + node = TrNode_child(node); + break; + } + //Nested Trie code + if (IS_FUNCTOR_NODE(TrNode_parent(node)) && (strcmp(YAP_AtomName(YAP_NameOfFunctor((YAP_Functor)(~ApplTag & TrNode_entry(TrNode_parent(node))))), NESTED_TRIE_TERM) == 0)) { + /* nested trie: stop procedure and return nested trie node */ + return node; + } + PUSH_DOWN(stack_args, TrNode_entry(node), stack_top); + if (!IS_FUNCTOR_NODE(node)) + count++; + } while (TrNode_next(node) == NULL && TrNode_child(TrNode_parent(node)) == node); + if (!count) + return NULL; + while (IS_FUNCTOR_NODE(TrNode_parent(node))) { + node = TrNode_parent(node); + PUSH_DOWN(stack_args, TrNode_entry(node), stack_top); + } + TrNode temp = TrNode_child(TrNode_parent(node)); + if (IS_HASH_NODE(temp)) { + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) temp; + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + do { + if ((temp = *--bucket)) { + while(TrNode_next(temp) != NULL) { + if (TrNode_entry(temp) == PairEndTag) + return NULL; + temp = TrNode_next(temp); + } + } + } while (bucket != first_bucket); + } else { + while(TrNode_next(temp) != NULL) { + if (TrNode_entry(temp) == PairEndTag) + return NULL; + temp = TrNode_next(temp); + } + } + + t = update_depth_breadth_trie(engine, depth_node, opt_level, construct_function, destruct_function, copy_function, correct_order_function); + + /* do depth reduction */ + DATA_DESTRUCT_FUNCTION = destruct_function; + node = trie_node_check_insert(TrNode_parent(node), t); + node = trie_node_check_insert(node, PairEndTag); + INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE); + temp = TrNode_parent(leaf); + remove_child_nodes(TrNode_child(temp)); + remove_entry(temp); + return node; +} + + +inline +TrNode core_breadth_reduction(TrEngine engine, TrNode node, TrNode breadth_node, YAP_Int opt_level, void (*construct_function)(TrNode), void (*destruct_function)(TrNode), void (*copy_function)(TrNode, TrNode), void (*correct_order_function)(void)) { + YAP_Term t, *stack_top; + int count = -1; + TrNode child; + /* collect breadth nodes */ + stack_args_base = stack_args = AUXILIARY_TERM_STACK; + stack_top = AUXILIARY_TERM_STACK + CURRENT_AUXILIARY_TERM_STACK_SIZE - 1; + node = TrNode_parent(TrNode_parent(node)); +// printf("1\n"); +// printf("start node: "); displaynode(node); + if (IS_FUNCTOR_NODE(node)) { +// printf("2\n"); + while(IS_FUNCTOR_NODE(node)) + node = TrNode_parent(node); + child = TrNode_child(node); + while((TrNode_next(child) == NULL) && (TrNode_child(TrNode_parent(child)) == child) && (TrNode_entry(TrNode_child(child)) != PairEndTag)) + child = TrNode_child(child); + } else + child = TrNode_child(node); +/* printf("start node: "); displaynode(child);*/ + if (IS_HASH_NODE(child)) { + printf("warning\n"); + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) child; + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + do { + if ((child = *--bucket)) { + do { + if (TrNode_entry(child) == PairEndTag) + return core_breadth_reduction(engine, child, breadth_node, opt_level, construct_function, destruct_function, copy_function, correct_order_function); + while (IS_FUNCTOR_NODE(child)) { + child = TrNode_child(child); + if (IS_HASH_NODE(child)) { // gets first child in the hash + TrNode *first_bucket2, *bucket2; + TrHash hash2 = (TrHash) child; + first_bucket2 = TrHash_buckets(hash2); + bucket2 = first_bucket2 + TrHash_num_buckets(hash2); + while(!(child = *--bucket2)); + } + } + TrNode temp = TrNode_child(child); + if (IS_HASH_NODE(temp)) { + TrNode *first_bucket2, *bucket2; + TrHash hash2 = (TrHash) temp; + first_bucket2 = TrHash_buckets(hash2); + bucket2 = first_bucket2 + TrHash_num_buckets(hash2); + do { + if ((temp = *--bucket2)) { + while((temp != NULL) && (TrNode_entry(temp) != PairEndTag)) + temp = TrNode_next(temp); + } + } while (bucket2 != first_bucket2 && temp == NULL); + } else { + while((temp != NULL) && (TrNode_entry(temp) != PairEndTag)) + temp = TrNode_next(temp); + } + if (temp == NULL) + return NULL; + //Nested Trie code + if (IS_FUNCTOR_NODE(TrNode_parent(child)) && (strcmp(YAP_AtomName(YAP_NameOfFunctor((YAP_Functor)(~ApplTag & TrNode_entry(TrNode_parent(child))))), NESTED_TRIE_TERM) == 0)) { + /* nested trie: stop procedure and return nested trie node */ + return child; + } + PUSH_DOWN(stack_args, TrNode_entry(child), stack_top); + count++; + if (IS_FUNCTOR_NODE(TrNode_parent(child))) { + temp = TrNode_parent(child); + while (IS_FUNCTOR_NODE(temp)) { + PUSH_DOWN(stack_args, TrNode_entry(temp), stack_top); + temp = TrNode_parent(temp); + } + while ((TrNode_next(child) == NULL) && IS_FUNCTOR_NODE(TrNode_parent(child)) && (bucket == first_bucket)) + child = TrNode_parent(child); + } + child = TrNode_next(child); + } while (child); + } + } while (bucket != first_bucket); + } else { + do { + if (TrNode_entry(child) == PairEndTag) + return core_breadth_reduction(engine, child, breadth_node, opt_level, construct_function, destruct_function, copy_function, correct_order_function); + while (IS_FUNCTOR_NODE(child)) { + child = TrNode_child(child); + if (IS_HASH_NODE(child)) { // gets first child in the hash + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) child; + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + while(!(child = *--bucket)); + } + } + TrNode temp = TrNode_child(child); + if (IS_HASH_NODE(temp)) { + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) temp; + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + do { + if ((temp = *--bucket)) { + while((temp != NULL) && (TrNode_entry(temp) != PairEndTag)) { + temp = TrNode_next(temp); + } + } + } while (bucket != first_bucket && temp == NULL); + } else { + while((temp != NULL) && (TrNode_entry(temp) != PairEndTag)) + temp = TrNode_next(temp); + } + if (temp == NULL) + return NULL; + //Nested Trie code + if (IS_FUNCTOR_NODE(TrNode_parent(child)) && (strcmp(YAP_AtomName(YAP_NameOfFunctor((YAP_Functor)(~ApplTag & TrNode_entry(TrNode_parent(child))))), NESTED_TRIE_TERM) == 0)) { + /* nested trie: stop procedure and return nested trie node */ + return child; + } + PUSH_DOWN(stack_args, TrNode_entry(child), stack_top); + count++; + if (IS_FUNCTOR_NODE(TrNode_parent(child))) { + temp = TrNode_parent(child); + while (IS_FUNCTOR_NODE(temp)) { + PUSH_DOWN(stack_args, TrNode_entry(temp), stack_top); + temp = TrNode_parent(temp); + } + while ((TrNode_next(child) == NULL) && IS_FUNCTOR_NODE(TrNode_parent(child))) + child = TrNode_parent(child); + } + child = TrNode_next(child); + } while (child); +// printf("pass through\n"); + } + if (!count) { + /* termination condition */ + core_set_trie_db_return_term(get_return_node_term(TrNode_child(node))); + node = TrNode_parent(node); + remove_child_nodes(TrNode_child(node)); + TrNode_child(node) = NULL; + return NULL; + } + + t = update_depth_breadth_trie(engine, breadth_node, opt_level, construct_function, destruct_function, copy_function, correct_order_function); + + /* do breadth reduction */ + DATA_DESTRUCT_FUNCTION = destruct_function; + remove_child_nodes(TrNode_child(node)); + TrNode_child(node) = NULL; + node = trie_node_check_insert(node, t); + node = trie_node_check_insert(node, PairEndTag); + INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE); +// printf("end node: "); displaynode(node); + return node; +} + + +inline +YAP_Term get_return_node_term(TrNode node) { + YAP_Term args[1], t; + if (IS_HASH_NODE(node)) { + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) node; + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + while(!(node = *--bucket)); + t = TrNode_entry(node); + } else if (IS_FUNCTOR_NODE(node)) { + args[0] = get_return_node_term(TrNode_child(node)); + t = YAP_MkApplTerm((YAP_Functor)(~ApplTag & TrNode_entry(node)), 1, args); + } else { + t = TrNode_entry(node); + } + return t; +} + + +inline +int traverse_get_counter(TrNode node) { + int count = -1; + while (TrNode_entry(node) != PairEndTag) { + if (!IS_FUNCTOR_NODE(node)) + count++; + node = TrNode_child(node); + if (IS_HASH_NODE(node)) { + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) node; + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + do { + if ((node = *--bucket)) { + while(TrNode_next(node) != NULL) + node = TrNode_next(node); + } + } while (bucket != first_bucket); + } else { + while(TrNode_next(node) != NULL) + node = TrNode_next(node); + } + } + return atoi(YAP_AtomName(YAP_AtomOfTerm(TrNode_entry(TrNode_child(node)))) + 1) - count; +} + + +inline +YAP_Term generate_label(YAP_Int Index) { + char label[20]; + sprintf(label,"L%ld", Index); + return YAP_MkAtomTerm(YAP_LookupAtom(label)); +} + + +inline +YAP_Term update_depth_breadth_trie(TrEngine engine, TrNode root, YAP_Int opt_level, void (*construct_function)(TrNode), void (*destruct_function)(TrNode), void (*copy_function)(TrNode, TrNode), void (*correct_order_function)(void)) { + TrNode node = root, remember = NULL; + int count = -1, cnt = -1, c_cnt = 0, f_cnt = 0; + YAP_Int BAK_CURRENT_TRIE_MODE = CURRENT_TRIE_MODE; + YAP_Term t, tt, ret_t = PairEndTag; + if (opt_level > 0) + CURRENT_TRIE_MODE = TRIE_MODE_MINIMAL; + else + CURRENT_TRIE_MODE = TRIE_MODE_STANDARD; + CURRENT_TRIE_ENGINE = engine; + DATA_DESTRUCT_FUNCTION = destruct_function; + DATA_COPY_FUNCTION = copy_function; + do { + t = POP_UP(stack_args); + node = trie_node_check_insert(node, t); + if (!IS_FUNCTOR_NODE(node)) + count++; + if (opt_level > 0) { + // Optimization 1: when asserting a non-minimal you can reuse minimal. + if (TrNode_entry(node) == PairEndTag) { + // Check to find the longest re-usage + TrNode c_node = trie_node_check(TrNode_parent(node), t), end_node; + c_cnt = 0; + f_cnt = 0; + while (c_node != NULL) { + if (stack_args_base != stack_args) { + c_cnt++; + tt = POP_UP(stack_args); + end_node = trie_node_check(c_node, PairEndTag); + c_node = trie_node_check(c_node, tt); + if ((c_node!= NULL) && !IS_FUNCTOR_NODE(c_node)) + f_cnt++; + if ((end_node != NULL)) { + count += f_cnt; + f_cnt = 0; + c_cnt = 0; + t = tt; + node = end_node; + } + } else { + // reached the end + node = c_node; + c_node = NULL; + count += f_cnt; + f_cnt = 0; + c_cnt = 0; + } + } + stack_args += c_cnt; + } + if (TrNode_entry(node) == PairEndTag) { + if (count > TRIE_DEPTH_BREADTH_MIN_PREFIX - 2) { + TRIE_DEPTH_BREADTH_OPT_COUNT[0]++; + cnt = -1; // reset optimization 3 counter + count = 0; + node = trie_node_check_insert(root, TrNode_entry(TrNode_child(node))); + if (TrNode_child(node) != NULL) + cnt++; + node = trie_node_check_insert(node, t); + if (!IS_FUNCTOR_NODE(node)) { + count++; + if (TrNode_child(node) != NULL) + cnt++; + } + } else { + CURRENT_TRIE_MODE = TRIE_MODE_STANDARD; + node = trie_node_check_insert(TrNode_parent(node), t); + CURRENT_TRIE_MODE = TRIE_MODE_MINIMAL; + } + } + } + if (opt_level > 2) { + // Optimization 3: when asserting common prefix of size 2 or longer. + // 1) remember last node and count + // 2) after normal assertion ends go to remembered node, count + // 3) assert PairEndTag to triger optimization 2 + if (TrNode_child(node) != NULL) { + if (!IS_FUNCTOR_NODE(node)) + cnt++; + } else { + if ((remember == NULL) && (cnt > 0) && (cnt > TRIE_DEPTH_BREADTH_MIN_PREFIX - 2)) { + TRIE_DEPTH_BREADTH_OPT_COUNT[1]--; + TRIE_DEPTH_BREADTH_OPT_COUNT[2]++; + remember = node; + do { + remember = TrNode_parent(remember); + } while(IS_FUNCTOR_NODE(remember)); + } + } + } + } while (stack_args_base != stack_args); + do { + t = PairEndTag; + if (opt_level > 1) { + // Optimization 2: when asserting a more minimal you can reuse it + // a) Traverse and find the lowest L and the length of branch LN = (L? - (length - 1) + count) + // b) insert LN + // c) copy childs of node + // d) remove childs of node + // e) insert ] + // f) insert LN + // g) REORDER Entries + if ((TrNode_child(node) != NULL) && (TrNode_entry(TrNode_child(node)) != PairEndTag) && (count > TRIE_DEPTH_BREADTH_MIN_PREFIX - 2)) { + TRIE_DEPTH_BREADTH_OPT_COUNT[1]++; + t = generate_label(traverse_get_counter(node)); + root = trie_node_check_insert(root, t); + TrNode_child(root) = copy_child_nodes(root, TrNode_child(node)); + remove_child_nodes(TrNode_child(node)); + TrNode_child(node) = NULL; + } + } + node = trie_node_check_insert(node, PairEndTag); + + if (t == PairEndTag) { + if (TrNode_child(node)) { + t = TrNode_entry(TrNode_child(node)); + } else { + LABEL_COUNTER += count; + t = generate_label(LABEL_COUNTER); + node = trie_node_check_insert(node, t); + INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE); + (*construct_function)(node); + } + } else { + node = trie_node_check_insert(node, t); + INCREMENT_ENTRIES(CURRENT_TRIE_ENGINE); + (*construct_function)(node); + (*correct_order_function)(); + } + // Optimization 3: part 2 + node = remember; + count = cnt; + remember = NULL; + if (ret_t == PairEndTag) + ret_t = t; + } while(node != NULL); + + CURRENT_TRIE_MODE = BAK_CURRENT_TRIE_MODE; + return ret_t; +} + + +inline +YAP_Int core_db_trie_get_optimization_level_count(YAP_Int opt_level) { + return TRIE_DEPTH_BREADTH_OPT_COUNT[opt_level - 1]; +} diff --git a/library/tries/core_dbtries.h b/library/tries/core_dbtries.h new file mode 100644 index 000000000..8b74218ab --- /dev/null +++ b/library/tries/core_dbtries.h @@ -0,0 +1,229 @@ +/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% $Date: 2010-06-30 17:05:24 +0200 (Wed, 30 Jun 2010) $ +% $Revision: 1 $ +% +% This file is part of YAP & ProbLog +% http://www.dcc.fc.up.pt/~vsc/Yap/index.html +% http://dtai.cs.kuleuven.be/problog +% +% ProbLog was developed at Katholieke Universiteit Leuven & +% University of Porto +% +% Copyright 2010 Katholieke Universiteit Leuven & University of Porto +% +% Main authors of this file: Mantadelis Theofrastos, Ricardo Rocha +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Artistic License 2.0 +% +% Copyright (c) 2000-2006, The Perl Foundation. +% +% Everyone is permitted to copy and distribute verbatim copies of this +% license document, but changing it is not allowed. Preamble +% +% This license establishes the terms under which a given free software +% Package may be copied, modified, distributed, and/or +% redistributed. The intent is that the Copyright Holder maintains some +% artistic control over the development of that Package while still +% keeping the Package available as open source and free software. +% +% You are always permitted to make arrangements wholly outside of this +% license directly with the Copyright Holder of a given Package. If the +% terms of this license do not permit the full use that you propose to +% make of the Package, you should contact the Copyright Holder and seek +% a different licensing arrangement. Definitions +% +% "Copyright Holder" means the individual(s) or organization(s) named in +% the copyright notice for the entire Package. +% +% "Contributor" means any party that has contributed code or other +% material to the Package, in accordance with the Copyright Holder's +% procedures. +% +% "You" and "your" means any person who would like to copy, distribute, +% or modify the Package. +% +% "Package" means the collection of files distributed by the Copyright +% Holder, and derivatives of that collection and/or of those files. A +% given Package may consist of either the Standard Version, or a +% Modified Version. +% +% "Distribute" means providing a copy of the Package or making it +% accessible to anyone else, or in the case of a company or +% organization, to others outside of your company or organization. +% +% "Distributor Fee" means any fee that you charge for Distributing this +% Package or providing support for this Package to another party. It +% does not mean licensing fees. +% +% "Standard Version" refers to the Package if it has not been modified, +% or has been modified only in ways explicitly requested by the +% Copyright Holder. +% +% "Modified Version" means the Package, if it has been changed, and such +% changes were not explicitly requested by the Copyright Holder. +% +% "Original License" means this Artistic License as Distributed with the +% Standard Version of the Package, in its current version or as it may +% be modified by The Perl Foundation in the future. +% +% "Source" form means the source code, documentation source, and +% configuration files for the Package. +% +% "Compiled" form means the compiled bytecode, object code, binary, or +% any other form resulting from mechanical transformation or translation +% of the Source form. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Permission for Use and Modification Without Distribution +% +% (1) You are permitted to use the Standard Version and create and use +% Modified Versions for any purpose without restriction, provided that +% you do not Distribute the Modified Version. +% +% Permissions for Redistribution of the Standard Version +% +% (2) You may Distribute verbatim copies of the Source form of the +% Standard Version of this Package in any medium without restriction, +% either gratis or for a Distributor Fee, provided that you duplicate +% all of the original copyright notices and associated disclaimers. At +% your discretion, such verbatim copies may or may not include a +% Compiled form of the Package. +% +% (3) You may apply any bug fixes, portability changes, and other +% modifications made available from the Copyright Holder. The resulting +% Package will still be considered the Standard Version, and as such +% will be subject to the Original License. +% +% Distribution of Modified Versions of the Package as Source +% +% (4) You may Distribute your Modified Version as Source (either gratis +% or for a Distributor Fee, and with or without a Compiled form of the +% Modified Version) provided that you clearly document how it differs +% from the Standard Version, including, but not limited to, documenting +% any non-standard features, executables, or modules, and provided that +% you do at least ONE of the following: +% +% (a) make the Modified Version available to the Copyright Holder of the +% Standard Version, under the Original License, so that the Copyright +% Holder may include your modifications in the Standard Version. (b) +% ensure that installation of your Modified Version does not prevent the +% user installing or running the Standard Version. In addition, the +% modified Version must bear a name that is different from the name of +% the Standard Version. (c) allow anyone who receives a copy of the +% Modified Version to make the Source form of the Modified Version +% available to others under (i) the Original License or (ii) a license +% that permits the licensee to freely copy, modify and redistribute the +% Modified Version using the same licensing terms that apply to the copy +% that the licensee received, and requires that the Source form of the +% Modified Version, and of any works derived from it, be made freely +% available in that license fees are prohibited but Distributor Fees are +% allowed. +% +% Distribution of Compiled Forms of the Standard Version or +% Modified Versions without the Source +% +% (5) You may Distribute Compiled forms of the Standard Version without +% the Source, provided that you include complete instructions on how to +% get the Source of the Standard Version. Such instructions must be +% valid at the time of your distribution. If these instructions, at any +% time while you are carrying out such distribution, become invalid, you +% must provide new instructions on demand or cease further +% distribution. If you provide valid instructions or cease distribution +% within thirty days after you become aware that the instructions are +% invalid, then you do not forfeit any of your rights under this +% license. +% +% (6) You may Distribute a Modified Version in Compiled form without the +% Source, provided that you comply with Section 4 with respect to the +% Source of the Modified Version. +% +% Aggregating or Linking the Package +% +% (7) You may aggregate the Package (either the Standard Version or +% Modified Version) with other packages and Distribute the resulting +% aggregation provided that you do not charge a licensing fee for the +% Package. Distributor Fees are permitted, and licensing fees for other +% components in the aggregation are permitted. The terms of this license +% apply to the use and Distribution of the Standard or Modified Versions +% as included in the aggregation. +% +% (8) You are permitted to link Modified and Standard Versions with +% other works, to embed the Package in a larger work of your own, or to +% build stand-alone binary or bytecode versions of applications that +% include the Package, and Distribute the result without restriction, +% provided the result does not expose a direct interface to the Package. +% +% Items That are Not Considered Part of a Modified Version +% +% (9) Works (including, but not limited to, modules and scripts) that +% merely extend or make use of the Package, do not, by themselves, cause +% the Package to be a Modified Version. In addition, such works are not +% considered parts of the Package itself, and are not subject to the +% terms of this license. +% +% General Provisions +% +% (10) Any use, modification, and distribution of the Standard or +% Modified Versions is governed by this Artistic License. By using, +% modifying or distributing the Package, you accept this license. Do not +% use, modify, or distribute the Package, if you do not accept this +% license. +% +% (11) If your Modified Version has been derived from a Modified Version +% made by someone other than you, you are nevertheless required to +% ensure that your Modified Version complies with the requirements of +% this license. +% +% (12) This license does not grant you the right to use any trademark, +% service mark, tradename, or logo of the Copyright Holder. +% +% (13) This license includes the non-exclusive, worldwide, +% free-of-charge patent license to make, have made, use, offer to sell, +% sell, import and otherwise transfer the Package with respect to any +% patent claims licensable by the Copyright Holder that are necessarily +% infringed by the Package. If you institute patent litigation +% (including a cross-claim or counterclaim) against any party alleging +% that the Package constitutes direct or contributory patent +% infringement, then this Artistic License to you shall terminate on the +% date that such litigation is filed. +% +% (14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT +% HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED +% WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +% PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT +% PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT +% HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, +% INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE +% OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ + + +/* --------------------------- */ +/* Defines */ +/* --------------------------- */ + +#define NESTED_TRIE_TERM "t" +#define PairEndTag PairEndEmptyTag + + +/* --------------------------- */ +/* API */ +/* --------------------------- */ + +inline void core_set_label_counter(YAP_Int value); +inline YAP_Int core_get_label_counter(void); +inline void core_initialize_depth_breadth_trie(TrNode node, TrNode *depth_node, TrNode *breadth_node); +inline void core_finalize_depth_breadth_trie(TrNode depth_node, TrNode breadth_node); +inline TrNode core_depth_reduction(TrEngine engine, TrNode node, TrNode depth_node, YAP_Int opt_level, void (*construct_function)(TrNode), void (*destruct_function)(TrNode), void (*copy_function)(TrNode, TrNode), void (*correct_order_function)(void)); +inline TrNode core_breadth_reduction(TrEngine engine, TrNode node, TrNode breadth_node, YAP_Int opt_level, void (*construct_function)(TrNode), void (*destruct_function)(TrNode), void (*copy_function)(TrNode, TrNode), void (*correct_order_function)(void)); +inline YAP_Term core_get_trie_db_return_term(void); +inline void core_set_trie_db_return_term(YAP_Term return_value); +inline YAP_Int core_db_trie_get_optimization_level_count(YAP_Int opt_level); +inline void core_depth_breadth_trie_replace_nested_trie(TrNode node, YAP_Int nested_trie_id, YAP_Term new_term); +inline YAP_Int core_get_trie_db_opt_min_prefix(void); +inline void core_set_trie_db_opt_min_prefix(YAP_Int min_prefix); From 0a6ba6a6786a488041b1dc2dd3cb19fd60e8c6d4 Mon Sep 17 00:00:00 2001 From: Theo Date: Mon, 19 Jul 2010 11:29:13 +0100 Subject: [PATCH 2/3] Hmm learning the git (half of the files were commited sorry guys) --- library/tries.yap | 23 ++- library/tries/Makefile.in | 6 +- library/tries/base_tries.c | 105 +++++++++- library/tries/base_tries.h | 20 ++ library/tries/core_tries.c | 382 +++++++++++++++++++++++++++++-------- library/tries/core_tries.h | 14 ++ library/tries/tries.c | 281 +++++++++++++++++++++++++++ 7 files changed, 746 insertions(+), 85 deletions(-) mode change 100644 => 100755 library/tries.yap diff --git a/library/tries.yap b/library/tries.yap old mode 100644 new mode 100755 index 096cbfa4a..569b69ce1 --- a/library/tries.yap +++ b/library/tries.yap @@ -37,7 +37,18 @@ put_trie_entry/4, get_trie_entry/3, remove_trie_entry/1, - print_trie/1 + print_trie/1, + trie_traverse_mode/1, + trie_disable_hash/0, + trie_enable_hash/0, + trie_traverse_first/2, + trie_traverse_next/2, + trie_to_list/2, + trie_to_depth_breadth_trie/4, + trie_to_depth_breadth_trie/6, + trie_get_depth_breadth_reduction_entry/1, + trie_get_depth_breadth_reduction_opt_level_count/2, + trie_replace_nested_trie/3 ]). :- load_foreign_files([tries], [], init_tries). @@ -51,3 +62,13 @@ trie_dup(Trie, CopyTrie) :- trie_traverse(Trie, Ref) :- trie_traverse(Trie, 0, Ref). + +trie_to_depth_breadth_trie(Trie, DepthBreadthTrie, FinalLabel, OptimizationLevel) :- + integer(OptimizationLevel), + trie_dup(Trie, CopyTrie), + trie_open(DepthBreadthTrie), + trie_depth_breadth(CopyTrie, DepthBreadthTrie, FinalLabel, OptimizationLevel, 0, _), + trie_close(CopyTrie). + +trie_to_depth_breadth_trie(Trie, DepthBreadthTrie, FinalLabel, OptimizationLevel, StartCounter, EndCounter) :- + trie_depth_breadth(Trie, DepthBreadthTrie, FinalLabel, OptimizationLevel, StartCounter, EndCounter). diff --git a/library/tries/Makefile.in b/library/tries/Makefile.in index 59db2e2e5..b8ddc06e2 100644 --- a/library/tries/Makefile.in +++ b/library/tries/Makefile.in @@ -44,13 +44,13 @@ SOBJS=tries.@SO@ itries.@SO@ all: $(SOBJS) -core_tries.o: $(srcdir)/core_tries.h $(srcdir)/core_tries.c +core_tries.o: $(srcdir)/core_tries.h $(srcdir)/core_tries.c $(srcdir)/core_dbtries.h $(srcdir)/core_dbtries.c $(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(srcdir)/core_tries.c -o core_tries.o -base_tries.o: $(srcdir)/core_tries.h $(srcdir)/base_tries.h $(srcdir)/base_tries.c +base_tries.o: $(srcdir)/core_tries.h $(srcdir)/base_tries.h $(srcdir)/base_tries.c $(srcdir)/core_dbtries.h $(srcdir)/base_dbtries.h $(srcdir)/base_dbtries.c $(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(srcdir)/base_tries.c -o base_tries.o -tries.o: $(srcdir)/core_tries.h $(srcdir)/base_tries.h $(srcdir)/tries.c +tries.o: $(srcdir)/core_tries.h $(srcdir)/base_tries.h $(srcdir)/tries.c $(srcdir)/core_dbtries.h $(srcdir)/base_dbtries.h $(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(srcdir)/tries.c -o tries.o base_itries.o: $(srcdir)/core_tries.h $(srcdir)/base_itries.h $(srcdir)/base_itries.c diff --git a/library/tries/base_tries.c b/library/tries/base_tries.c index 36c90e12b..75d14483b 100644 --- a/library/tries/base_tries.c +++ b/library/tries/base_tries.c @@ -18,6 +18,12 @@ #include "base_tries.h" +/* -------------------------- */ +/* Local Procedures */ +/* -------------------------- */ + +static TrData get_data_from_trie_node(TrNode node); + /* -------------------------- */ /* Local Variables */ @@ -26,6 +32,7 @@ static TrEngine TRIE_ENGINE; static TrEntry FIRST_TRIE, CURRENT_TRIE; +static YAP_Int CURRENT_TRAVERSE_MODE; /* -------------------------- */ @@ -36,6 +43,7 @@ inline void trie_init_module(void) { TRIE_ENGINE = core_trie_init_module(); FIRST_TRIE = NULL; + CURRENT_TRAVERSE_MODE = TRAVERSE_MODE_FORWARD; return; } @@ -192,7 +200,10 @@ TrData trie_traverse_init(TrEntry trie, TrData init_data) { if (init_data) { data = TrData_next(init_data); } else { - data = TrEntry_first_data(trie); + if (CURRENT_TRAVERSE_MODE == TRAVERSE_MODE_FORWARD) + data = TrEntry_first_data(trie); + else + data = TrEntry_last_data(trie); } TrEntry_traverse_data(trie) = data; return data; @@ -205,7 +216,13 @@ TrData trie_traverse_cont(TrEntry trie) { data = TrEntry_traverse_data(trie); if (data) { - data = TrData_next(data); + if (CURRENT_TRAVERSE_MODE == TRAVERSE_MODE_FORWARD) + data = TrData_next(data); + else { + data = TrData_previous(data); + if (data == TrData_previous(TrEntry_first_data(trie))) + data = NULL; + } TrEntry_traverse_data(trie) = data; } return data; @@ -305,3 +322,87 @@ void trie_print(TrEntry trie) { core_trie_print(TrEntry_trie(trie), NULL); return; } + + +inline +void trie_data_construct(TrNode node) { + TrData data; + + new_trie_data(data, CURRENT_TRIE, node); + PUT_DATA_IN_LEAF_TRIE_NODE(node, data); + return; +} + + +inline +void trie_set_traverse_mode(YAP_Int mode) { + CURRENT_TRAVERSE_MODE = mode; + return; +} + + +inline +YAP_Int trie_get_traverse_mode(void) { + return CURRENT_TRAVERSE_MODE; +} + + +inline +TrData trie_traverse_first(TrEntry trie) { + TrData data; + if (CURRENT_TRAVERSE_MODE == TRAVERSE_MODE_FORWARD) + data = TrEntry_first_data(trie); + else + data = TrEntry_last_data(trie); + return data; +} + + +inline +TrData trie_traverse_next(TrData cur) { + TrData data = NULL; + if (cur) { + if (CURRENT_TRAVERSE_MODE == TRAVERSE_MODE_FORWARD) + data = TrData_next(cur); + else { + data = TrData_previous(cur); + if (data == TrData_previous(TrEntry_first_data(TrData_trie(cur)))) + data = NULL; + } + } + return data; +} + + +inline +void trie_disable_hash_table(void) { + core_disable_hash_table(); + return; +} + + +inline +void trie_enable_hash_table(void) { + core_enable_hash_table(); + return; +} + + +/* -------------------------- */ +/* Local Procedures */ +/* -------------------------- */ + +static +TrData get_data_from_trie_node(TrNode node) { + while(!IS_LEAF_TRIE_NODE(node)) + node = TrNode_child(node); + return (TrData) GET_DATA_FROM_LEAF_TRIE_NODE(node); +} + + +inline +YAP_Term trie_to_list(TrEntry trie) { + return core_trie_to_list(TrEntry_trie(trie)); +} + +#include "base_dbtries.c" diff --git a/library/tries/base_tries.h b/library/tries/base_tries.h index e8c7a8788..55429313c 100644 --- a/library/tries/base_tries.h +++ b/library/tries/base_tries.h @@ -7,6 +7,14 @@ +/* --------------------------- */ +/* Defines */ +/* --------------------------- */ + +#define TRAVERSE_MODE_FORWARD 0 +#define TRAVERSE_MODE_BACKWARD 1 + + /* --------------------------- */ /* Structs */ /* --------------------------- */ @@ -126,3 +134,15 @@ inline void trie_stats(YAP_Int *memory, YAP_Int *tries, YAP_Int *entries, YA inline void trie_max_stats(YAP_Int *memory, YAP_Int *tries, YAP_Int *entries, YAP_Int *nodes); inline void trie_usage(TrEntry trie, YAP_Int *entries, YAP_Int *nodes, YAP_Int *virtual_nodes); inline void trie_print(TrEntry trie); + +inline void trie_data_construct(TrNode node); +inline void trie_set_traverse_mode(YAP_Int mode); +inline YAP_Int trie_get_traverse_mode(void); +inline TrData trie_traverse_first(TrEntry trie); +inline TrData trie_traverse_next(TrData data); +inline void trie_disable_hash_table(void); +inline void trie_enable_hash_table(void); + +inline YAP_Term trie_to_list(TrEntry trie); + +#include "base_dbtries.h" diff --git a/library/tries/core_tries.c b/library/tries/core_tries.c index 7655ed088..59248403b 100644 --- a/library/tries/core_tries.c +++ b/library/tries/core_tries.c @@ -39,6 +39,9 @@ static void traverse_and_save(TrNode node, FILE *file, int float_block); static void traverse_and_load(TrNode parent, FILE *file); static void traverse_and_print(TrNode node, int *arity, char *str, int str_index, int mode); +static YAP_Term trie_to_list(TrNode node); +static YAP_Term trie_to_list_node(TrNode node); +static YAP_Term trie_to_list_floats(TrNode node); /* -------------------------- */ @@ -58,6 +61,7 @@ static void (*DATA_ADD_FUNCTION)(TrNode, TrNode); static void (*DATA_COPY_FUNCTION)(TrNode, TrNode); static void (*DATA_DESTRUCT_FUNCTION)(TrNode); +static YAP_Int TRIE_DISABLE_HASH_TABLE = 0; /* -------------------------- */ @@ -82,7 +86,7 @@ TrNode trie_node_check_insert(TrNode parent, YAP_Term t) { child = *bucket; count = 0; while (child) { - if (TrNode_entry(child) == t) + if ((TrNode_entry(child) == t) || (((TrNode_entry(child) == PairEndTermTag) || (TrNode_entry(child) == PairEndEmptyTag)) && ((CURRENT_TRIE_MODE & TRIE_MODE_MINIMAL) == TRIE_MODE_MINIMAL))) return child; count++; child = TrNode_next(child); @@ -108,9 +112,9 @@ TrNode trie_node_check_insert(TrNode parent, YAP_Term t) { new_bucket = TrHash_bucket(hash, HASH_TERM(TrNode_entry(chain), seed)); next = TrNode_next(chain); TrNode_next(chain) = *new_bucket; - TrNode_previous(chain) = AS_TR_NODE_NEXT(bucket); - if (*new_bucket) - TrNode_previous(*new_bucket) = chain; + TrNode_previous(chain) = AS_TR_NODE_NEXT(bucket); + if (*new_bucket) + TrNode_previous(*new_bucket) = chain; *new_bucket = chain; chain = next; } while (chain); @@ -121,14 +125,14 @@ TrNode trie_node_check_insert(TrNode parent, YAP_Term t) { } else { int count = 0; do { - if (TrNode_entry(child) == t) + if ((TrNode_entry(child) == t) || (((TrNode_entry(child) == PairEndTermTag) || (TrNode_entry(child) == PairEndEmptyTag)) && ((CURRENT_TRIE_MODE & TRIE_MODE_MINIMAL) == TRIE_MODE_MINIMAL))) return child; count++; child = TrNode_next(child); } while (child); new_trie_node(child, t, parent, NULL, TrNode_child(parent), NULL); TrNode_previous(TrNode_child(parent)) = child; - if (++count > MAX_NODES_PER_TRIE_LEVEL) { + if ((++count > MAX_NODES_PER_TRIE_LEVEL) && (TRIE_DISABLE_HASH_TABLE == 0)) { /* alloc a new trie hash */ TrHash hash; TrNode chain, next, *bucket; @@ -139,8 +143,8 @@ TrNode trie_node_check_insert(TrNode parent, YAP_Term t) { next = TrNode_next(chain); TrNode_next(chain) = *bucket; TrNode_previous(chain) = AS_TR_NODE_NEXT(bucket); - if (*bucket) - TrNode_previous(*bucket) = chain; + if (*bucket) + TrNode_previous(*bucket) = chain; *bucket = chain; chain = next; } while (chain); @@ -199,6 +203,45 @@ TrNode trie_node_check(TrNode parent, YAP_Term t) { } +static inline +YAP_Term trie_to_list_create_simple(const char *atom_name, TrNode node) { + YAP_Functor f = YAP_MkFunctor(YAP_LookupAtom(atom_name), 1); + YAP_Term child = trie_to_list(TrNode_child(node)); + + return YAP_MkApplTerm(f, 1, &child); +} + + +static inline +YAP_Term trie_to_list_create_simple_end(const char *atom_name, TrNode node) { + YAP_Atom atom = YAP_LookupAtom(atom_name); + + if (IS_LEAF_TRIE_NODE(node)) { + return YAP_MkAtomTerm(atom); + } else { + YAP_Functor f = YAP_MkFunctor(atom, 1); + YAP_Term child = trie_to_list(TrNode_child(node)); + return YAP_MkApplTerm(f, 1, &child); + } +} + + +static inline +YAP_Term trie_to_list_create_two(const char *atom_name, TrNode node, YAP_Term operand) { + YAP_Atom atom = YAP_LookupAtom(atom_name); + + if(IS_LEAF_TRIE_NODE(node)) { + YAP_Functor f = YAP_MkFunctor(atom, 1); + return YAP_MkApplTerm(f, 1, &operand); + } else { + YAP_Functor f = YAP_MkFunctor(atom, 2); + YAP_Term args[2] = { + operand, trie_to_list(TrNode_child(node)) + }; + return YAP_MkApplTerm(f, 2, args); + } +} + /* -------------------------- */ /* API */ @@ -523,6 +566,27 @@ void core_trie_print(TrNode node, void (*print_function)(TrNode)) { } +inline +void core_disable_hash_table(void) { + TRIE_DISABLE_HASH_TABLE = 1; +} + + +inline +void core_enable_hash_table(void) { + TRIE_DISABLE_HASH_TABLE = 0; +} + + +inline +YAP_Term core_trie_to_list(TrNode node) { + TrNode root = TrNode_child(node); + + if (root) + return trie_to_list(root); + else + return YAP_MkAtomTerm(YAP_LookupAtom("empty")); +} /* -------------------------- */ @@ -558,32 +622,32 @@ TrNode put_entry(TrNode node, YAP_Term entry) { node = trie_node_check_insert(node, FloatEndTag); } else if (YAP_IsPairTerm(t)) { node = trie_node_check_insert(node, PairInitTag); - if (CURRENT_TRIE_MODE == TRIE_MODE_STANDARD) { + if ((CURRENT_TRIE_MODE & TRIE_MODE_REVERSE) == TRIE_MODE_STANDARD) { do { - node = put_entry(node, YAP_HeadOfTerm(t)); - t = YAP_Deref(YAP_TailOfTerm(t)); + node = put_entry(node, YAP_HeadOfTerm(t)); + t = YAP_Deref(YAP_TailOfTerm(t)); } while (YAP_IsPairTerm(t)); if (t == YAP_TermNil()) { - node = trie_node_check_insert(node, PairEndEmptyTag); + node = trie_node_check_insert(node, PairEndEmptyTag); } else { - node = put_entry(node, t); - node = trie_node_check_insert(node, PairEndTermTag); + node = put_entry(node, t); + node = trie_node_check_insert(node, PairEndTermTag); } - } else { /* TRIE_MODE_REVERSE */ + } else if (CURRENT_TRIE_MODE & TRIE_MODE_REVERSE) { /* TRIE_MODE_REVERSE */ YAP_Term *stack_list = stack_args; do { - PUSH_DOWN(stack_args, YAP_HeadOfTerm(t), stack_vars); - t = YAP_Deref(YAP_TailOfTerm(t)); + PUSH_DOWN(stack_args, YAP_HeadOfTerm(t), stack_vars); + t = YAP_Deref(YAP_TailOfTerm(t)); } while (YAP_IsPairTerm(t)); if (t == YAP_TermNil()) { - while (STACK_NOT_EMPTY(stack_args, stack_list)) - node = put_entry(node, POP_UP(stack_args)); - node = trie_node_check_insert(node, PairEndEmptyTag); + while (STACK_NOT_EMPTY(stack_args, stack_list)) + node = put_entry(node, POP_UP(stack_args)); + node = trie_node_check_insert(node, PairEndEmptyTag); } else { - PUSH_DOWN(stack_args, t, stack_vars); - while (STACK_NOT_EMPTY(stack_args, stack_list)) - node = put_entry(node, POP_UP(stack_args)); - node = trie_node_check_insert(node, PairEndTermTag); + PUSH_DOWN(stack_args, t, stack_vars); + while (STACK_NOT_EMPTY(stack_args, stack_list)) + node = put_entry(node, POP_UP(stack_args)); + node = trie_node_check_insert(node, PairEndTermTag); } } } else if (YAP_IsApplTerm(t)) { @@ -591,8 +655,8 @@ TrNode put_entry(TrNode node, YAP_Term entry) { if (f == FunctorComma) { node = trie_node_check_insert(node, CommaInitTag); do { - node = put_entry(node, YAP_ArgOfTerm(1, t)); - t = YAP_Deref(YAP_ArgOfTerm(2, t)); + node = put_entry(node, YAP_ArgOfTerm(1, t)); + t = YAP_Deref(YAP_ArgOfTerm(2, t)); } while (YAP_IsApplTerm(t) && YAP_FunctorOfTerm(t) == FunctorComma); node = put_entry(node, t); node = trie_node_check_insert(node, CommaEndTag); @@ -600,7 +664,7 @@ TrNode put_entry(TrNode node, YAP_Term entry) { int i; node = trie_node_check_insert(node, ApplTag | ((YAP_Term) f)); for (i = 1; i <= YAP_ArityOfFunctor(f); i++) - node = put_entry(node, YAP_ArgOfTerm(i, t)); + node = put_entry(node, YAP_ArgOfTerm(i, t)); } } else { fprintf(stderr, "***************************************\n"); @@ -618,10 +682,10 @@ TrNode check_entry(TrNode node, YAP_Term entry) { if (YAP_IsVarTerm(t)) { if (IsTrieVar(t, stack_vars, stack_vars_base)) { if (!(node = trie_node_check(node, MkTrieVar((stack_vars_base - 1 - (YAP_Term *)t) / 2)))) - return NULL; + return NULL; } else { if (!(node = trie_node_check(node, MkTrieVar((stack_vars_base - stack_vars) / 2)))) - return NULL; + return NULL; PUSH_UP(stack_vars, t, stack_args); *((YAP_Term *)t) = (YAP_Term)stack_vars; PUSH_UP(stack_vars, stack_vars, stack_args); @@ -650,63 +714,63 @@ TrNode check_entry(TrNode node, YAP_Term entry) { } else if (YAP_IsPairTerm(t)) { if (!(node = trie_node_check(node, PairInitTag))) return NULL; - if (CURRENT_TRIE_MODE == TRIE_MODE_STANDARD) { + if ((CURRENT_TRIE_MODE & TRIE_MODE_REVERSE) == TRIE_MODE_STANDARD) { do { - if (!(node = check_entry(node, YAP_HeadOfTerm(t)))) - return NULL; - t = YAP_Deref(YAP_TailOfTerm(t)); + if (!(node = check_entry(node, YAP_HeadOfTerm(t)))) + return NULL; + t = YAP_Deref(YAP_TailOfTerm(t)); } while (YAP_IsPairTerm(t)); if (t == YAP_TermNil()) { - if (!(node = trie_node_check(node, PairEndEmptyTag))) - return NULL; + if (!(node = trie_node_check(node, PairEndEmptyTag))) + return NULL; } else { - if (!(node = check_entry(node, t))) - return NULL; - if (!(node = trie_node_check(node, PairEndTermTag))) - return NULL; + if (!(node = check_entry(node, t))) + return NULL; + if (!(node = trie_node_check(node, PairEndTermTag))) + return NULL; } - } else { /* TRIE_MODE_REVERSE */ + } else if (CURRENT_TRIE_MODE & TRIE_MODE_REVERSE) { /* TRIE_MODE_REVERSE */ YAP_Term *stack_list = stack_args; do { - PUSH_DOWN(stack_args, YAP_HeadOfTerm(t), stack_vars); - t = YAP_Deref(YAP_TailOfTerm(t)); + PUSH_DOWN(stack_args, YAP_HeadOfTerm(t), stack_vars); + t = YAP_Deref(YAP_TailOfTerm(t)); } while (YAP_IsPairTerm(t)); if (t == YAP_TermNil()) { - while (STACK_NOT_EMPTY(stack_args, stack_list)) - if (!(node = check_entry(node, POP_UP(stack_args)))) - return NULL; - if (!(node = trie_node_check(node, PairEndEmptyTag))) - return NULL; + while (STACK_NOT_EMPTY(stack_args, stack_list)) + if (!(node = check_entry(node, POP_UP(stack_args)))) + return NULL; + if (!(node = trie_node_check(node, PairEndEmptyTag))) + return NULL; } else { - PUSH_DOWN(stack_args, t, stack_vars); - while (STACK_NOT_EMPTY(stack_args, stack_list)) - if (!(node = check_entry(node, POP_UP(stack_args)))) - return NULL; - if (!(node = trie_node_check(node, PairEndTermTag))) - return NULL; + PUSH_DOWN(stack_args, t, stack_vars); + while (STACK_NOT_EMPTY(stack_args, stack_list)) + if (!(node = check_entry(node, POP_UP(stack_args)))) + return NULL; + if (!(node = trie_node_check(node, PairEndTermTag))) + return NULL; } } } else if (YAP_IsApplTerm(t)) { YAP_Functor f = YAP_FunctorOfTerm(t); if (f == FunctorComma) { if (!(node = trie_node_check(node, CommaInitTag))) - return NULL; + return NULL; do { - if (!(node = check_entry(node, YAP_ArgOfTerm(1, t)))) - return NULL; - t = YAP_Deref(YAP_ArgOfTerm(2, t)); + if (!(node = check_entry(node, YAP_ArgOfTerm(1, t)))) + return NULL; + t = YAP_Deref(YAP_ArgOfTerm(2, t)); } while (YAP_IsApplTerm(t) && YAP_FunctorOfTerm(t) == FunctorComma); if (!(node = check_entry(node, t))) - return NULL; + return NULL; if (!(node = trie_node_check(node, CommaEndTag))) - return NULL; + return NULL; } else { int i; if (!(node = trie_node_check(node, ApplTag | ((YAP_Term) f)))) - return NULL; + return NULL; for (i = 1; i <= YAP_ArityOfFunctor(f); i++) - if (!(node = check_entry(node, YAP_ArgOfTerm(i, t)))) - return NULL; + if (!(node = check_entry(node, YAP_ArgOfTerm(i, t)))) + return NULL; } } else { fprintf(stderr, "***************************************\n"); @@ -729,10 +793,10 @@ YAP_Term get_entry(TrNode node, YAP_Term *stack_mark, TrNode *cur_node) { int i; stack_vars = &stack_vars_base[index + 1]; if (stack_vars > stack_args + 1) { - fprintf(stderr, "**************************************\n"); - fprintf(stderr, " Tries core module: term stack full\n"); - fprintf(stderr, "**************************************\n"); - } + fprintf(stderr, "**************************************\n"); + fprintf(stderr, " Tries core module: term stack full\n"); + fprintf(stderr, "**************************************\n"); + } for (i = index; i > CURRENT_INDEX; i--) stack_vars_base[i] = 0; CURRENT_INDEX = index; @@ -751,37 +815,37 @@ YAP_Term get_entry(TrNode node, YAP_Term *stack_mark, TrNode *cur_node) { } else if (YAP_IsPairTerm(t)) { if (t == PairInitTag) { YAP_Term t2; - if (CURRENT_TRIE_MODE == TRIE_MODE_STANDARD) { + if ((CURRENT_TRIE_MODE & TRIE_MODE_REVERSE) == TRIE_MODE_STANDARD) { YAP_Term *stack_aux = stack_mark; t = *stack_aux--; while (STACK_NOT_EMPTY(stack_aux, stack_args)) { t2 = *stack_aux--; t = YAP_MkPairTerm(t2, t); } - } else { /* TRIE_MODE_REVERSE */ + } else if (CURRENT_TRIE_MODE & TRIE_MODE_REVERSE) { /* TRIE_MODE_REVERSE */ YAP_Term *stack_aux = stack_mark; t = *stack_aux; - if (t == YAP_TermNil()) - stack_aux--; - else - t = POP_DOWN(stack_args); + if (t == YAP_TermNil()) + stack_aux--; + else + t = POP_DOWN(stack_args); while (STACK_NOT_EMPTY(stack_args, stack_aux)) { t2 = POP_DOWN(stack_args); t = YAP_MkPairTerm(t2, t); } } - stack_args = stack_mark; + stack_args = stack_mark; *cur_node = node; return t; } else if (t == PairEndEmptyTag) { - t = YAP_TermNil(); - PUSH_UP(stack_args, t, stack_vars); - node = TrNode_parent(node); - t = get_entry(node, &stack_args[1], &node); + t = YAP_TermNil(); + PUSH_UP(stack_args, t, stack_vars); + node = TrNode_parent(node); + t = get_entry(node, &stack_args[1], &node); PUSH_UP(stack_args, t, stack_vars); } else if (t == PairEndTermTag) { - node = TrNode_parent(node); - t = get_entry(node, stack_args, &node); + node = TrNode_parent(node); + t = get_entry(node, stack_args, &node); PUSH_UP(stack_args, t, stack_vars); } else if (t == CommaEndTag) { node = TrNode_parent(node); @@ -1555,3 +1619,163 @@ void traverse_and_print(TrNode node, int *arity, char *str, int str_index, int m } return; } + + +static +YAP_Term trie_to_list(TrNode node) { + YAP_Term tail = YAP_MkAtomTerm(YAP_LookupAtom("[]")); + +#define CONSUME_NODE_LIST \ + do { \ + /* add node result to list */ \ + tail = YAP_MkPairTerm(trie_to_list_node(node), tail); \ + } while((node = TrNode_next(node))); + + if (IS_HASH_NODE(node)) { + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) node; + + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + + /* iterate through valid hash positions and consume each list */ + do { + if (*--bucket) { + node = *bucket; + CONSUME_NODE_LIST; + } + } while (bucket != first_bucket); + } else { + CONSUME_NODE_LIST; + } +#undef CONSUME_NODE_LIST + + /* return list of trie options at this level */ + return tail; +} + + +static +YAP_Term trie_to_list_node(TrNode node) { + YAP_Term t = TrNode_entry(node); + + if(YAP_IsIntTerm(t) || YAP_IsAtomTerm(t)) { + return trie_to_list_create_two(YAP_IsIntTerm(t) ? "int" : "atom", node, t); + } else if (YAP_IsVarTerm(t)) { + int index = TrieVarIndex(t); + YAP_Term index_term = YAP_MkIntTerm((YAP_Int)index); + return trie_to_list_create_two("var", node, index_term); + } else if (YAP_IsPairTerm(t)) { + if(t == FloatInitTag) { + node = TrNode_child(node); /* consume FloatInitTag */ + YAP_Functor f = YAP_MkFunctor(YAP_LookupAtom("floats"), 1); + YAP_Term child = trie_to_list_floats(node); + return YAP_MkApplTerm(f, 1, &child); + } else if(t == PairInitTag) { + return trie_to_list_create_simple("list", node); + } else if (t == PairEndEmptyTag) { + return trie_to_list_create_simple_end("endlist", node); + } else if (t == CommaInitTag) { + return trie_to_list_create_simple("comma", node); + } else if (t == CommaEndTag) { + return trie_to_list_create_simple_end("endcomma", node); + } + } else if (ApplTag & t) { + YAP_Functor f = (YAP_Functor)(~ApplTag & t); + int arity = YAP_ArityOfFunctor(f); + YAP_Functor new_f = YAP_MkFunctor(YAP_LookupAtom("functor"), 3); + YAP_Term args[3] = { + YAP_MkAtomTerm(YAP_NameOfFunctor(f)), + YAP_MkIntTerm((YAP_Int)arity), + trie_to_list(TrNode_child(node)) + }; + return YAP_MkApplTerm(new_f, 3, args); + } + fprintf(stderr, "***************************************\n"); + fprintf(stderr, " Tries core module: unknown type tag\n"); + fprintf(stderr, "***************************************\n"); + + return YAP_MkAtomTerm(YAP_LookupAtom("fail")); +} + + +#define PUSH_NEW_FLOAT_TERM(val) \ + result = YAP_MkPairTerm( \ + trie_to_list_create_two("float", TrNode_child(node), YAP_MkFloatTerm(val)), \ + result); + + +#ifdef TAG_LOW_BITS_32 +static inline +YAP_Term trie_to_list_floats_tag_low_32(YAP_Term result, TrNode node, volatile YAP_Term **p, volatile double *f) { + if(IS_HASH_NODE(node)) { + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) node; + + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + + do { + if(*--bucket) { + node = *bucket; + + do { + *(*p + 1) = TrNode_entry(node); + PUSH_NEW_FLOAT_TERM(*f); + } while((node = TrNode_next(node))); + } + } while (bucket != first_bucket); + } else { + do { + *(*p + 1) = TrNode_entry(node); + PUSH_NEW_FLOAT_TERM(*f); + } while((node = TrNode_next(node))); + } + + return result; +} +#endif /* TAG_LOW_BITS_32 */ + + +static +YAP_Term trie_to_list_floats(TrNode node) { + volatile double f; + volatile YAP_Term *p; + YAP_Term result = YAP_MkAtomTerm(YAP_LookupAtom("[]")); + + p = (YAP_Term *)((void *) &f); /* to avoid gcc warning */ + if (IS_HASH_NODE(node)) { + TrNode *first_bucket, *bucket; + TrHash hash = (TrHash) node; + first_bucket = TrHash_buckets(hash); + bucket = first_bucket + TrHash_num_buckets(hash); + do { + if (*--bucket) { + node = *bucket; + do { + *p = TrNode_entry(node); +#ifdef TAG_LOW_BITS_32 + result = trie_to_list_floats_tag_low_32(result, TrNode_child(node), &p, &f); +#else + PUSH_NEW_FLOAT_TERM(f); +#endif /* TAG_LOW_BITS_32 */ + } while((node = TrNode_next(node))); + } + } while (bucket != first_bucket); + } else { + do { + *p = TrNode_entry(node); +#ifdef TAG_LOW_BITS_32 + result = trie_to_list_floats_tag_low_32(result, TrNode_child(node), &p, &f); +#else + PUSH_NEW_FLOAT_TERM(f); +#endif /* TAG_LOW_BITS_32 */ + } while((node = TrNode_next(node))); + } + + return result; +} +#undef PUSH_NEW_FLOAT_TERM + + +#include "core_dbtries.c" diff --git a/library/tries/core_tries.h b/library/tries/core_tries.h index ff5130f4f..f627911be 100644 --- a/library/tries/core_tries.h +++ b/library/tries/core_tries.h @@ -41,6 +41,8 @@ #define TRIE_MODE_STANDARD 0 #define TRIE_MODE_REVERSE 1 +#define TRIE_MODE_MINIMAL 2 +#define TRIE_MODE_REVMIN TRIE_MODE_REVERSE || TRIE_MODE_MINIMAL //3 #define TRIE_PRINT_NORMAL 0 #define TRIE_PRINT_FLOAT 1 @@ -273,6 +275,11 @@ typedef struct trie_hash { TrEngine_nodes(TR_ENGINE)-- +#define IS_FUNCTOR_NODE(N) (((ApplTag & TrNode_entry(N)) == ApplTag) && \ + (TrNode_entry(N) != PairInitTag) && \ + (TrNode_entry(N) != PairEndEmptyTag) && \ + (TrNode_entry(N) != PairEndTermTag)) + /* --------------------------- */ /* API */ @@ -300,3 +307,10 @@ inline void core_trie_stats(TrEngine engine, YAP_Int *memory, YAP_Int *tries inline void core_trie_max_stats(TrEngine engine, YAP_Int *memory, YAP_Int *tries, YAP_Int *entries, YAP_Int *nodes); inline void core_trie_usage(TrNode node, YAP_Int *entries, YAP_Int *nodes, YAP_Int *virtual_nodes); inline void core_trie_print(TrNode node, void (*print_function)(TrNode)); + +inline void core_disable_hash_table(void); +inline void core_enable_hash_table(void); + +inline YAP_Term core_trie_to_list(TrNode node); + +#include "core_dbtries.h" diff --git a/library/tries/tries.c b/library/tries/tries.c index 9e58fc1fb..712f1efb0 100644 --- a/library/tries/tries.c +++ b/library/tries/tries.c @@ -18,6 +18,14 @@ #include "base_tries.h" +/* -------------------------- */ +/* Structures */ +/* -------------------------- */ + +typedef struct { + YAP_Term value; +} db_trie_opt_level; + /* -------------------------- */ /* Procedures */ @@ -47,6 +55,23 @@ static int p_trie_stats(void); static int p_trie_max_stats(void); static int p_trie_usage(void); static int p_trie_print(void); + +static int p_trie_traverse_mode(void); +static int p_trie_disable_hash(void); +static int p_trie_enable_hash(void); +static int p_trie_traverse_first(void); +static int p_trie_traverse_next(void); + +static int p_trie_to_list(void); + +/* dbtries support */ +static int p_trie_depth_breadth(void); +static int p_trie_get_depth_breadth_reduction_current_data(void); +static int p_trie_get_db_opt_level_count_init(void); +static int p_trie_get_db_opt_level_count_cont(void); +static int p_trie_replace_nested_trie(void); +static int p_trie_db_opt_min_prefix(void); + /* backwards compatibility */ static int p_open_trie(void); static int p_close_trie(void); @@ -87,6 +112,22 @@ void init_tries(void) { YAP_UserCPredicate("trie_stats", p_trie_stats, 4); YAP_UserCPredicate("trie_max_stats", p_trie_max_stats, 4); YAP_UserCPredicate("trie_print", p_trie_print, 1); + + YAP_UserCPredicate("trie_traverse_mode", p_trie_traverse_mode, 1); + YAP_UserCPredicate("trie_disable_hash", p_trie_disable_hash, 0); + YAP_UserCPredicate("trie_enable_hash", p_trie_enable_hash, 0); + YAP_UserCPredicate("trie_traverse_first", p_trie_traverse_first, 2); + YAP_UserCPredicate("trie_traverse_next", p_trie_traverse_next, 2); + + YAP_UserCPredicate("trie_to_list", p_trie_to_list, 2); + + /* dbtries support */ + YAP_UserCPredicate("trie_depth_breadth", p_trie_depth_breadth, 6); + YAP_UserCPredicate("trie_get_depth_breadth_reduction_entry", p_trie_get_depth_breadth_reduction_current_data, 1); + YAP_UserBackCPredicate("trie_get_depth_breadth_reduction_opt_level_count", p_trie_get_db_opt_level_count_init, p_trie_get_db_opt_level_count_cont, 2, sizeof(db_trie_opt_level)); + YAP_UserCPredicate("trie_replace_nested_trie", p_trie_replace_nested_trie, 3); + YAP_UserCPredicate("trie_db_opt_min_prefix", p_trie_db_opt_min_prefix, 1); + /* backwards compatibility */ YAP_UserCPredicate("open_trie", p_open_trie, 1); YAP_UserCPredicate("close_trie", p_close_trie, 1); @@ -674,3 +715,243 @@ static int p_trie_print(void) { return TRUE; } #undef arg_trie + + +/* trie_traverse_mode(?Mode) */ +#define arg_mode YAP_ARG1 +static int p_trie_traverse_mode(void) { + YAP_Term mode_term; + const char *mode_str; + YAP_Int mode; + + /* get mode */ + if (YAP_IsVarTerm(arg_mode)) { + mode = trie_get_traverse_mode(); + if (mode == TRAVERSE_MODE_FORWARD) + mode_term = YAP_MkAtomTerm(YAP_LookupAtom("forward")); + else if (mode == TRAVERSE_MODE_BACKWARD) + mode_term = YAP_MkAtomTerm(YAP_LookupAtom("backward")); + else + return FALSE; + return YAP_Unify(arg_mode, mode_term); + } + + /* set mode */ + mode_str = YAP_AtomName(YAP_AtomOfTerm(arg_mode)); + if (!strcmp(mode_str, "forward")) + mode = TRAVERSE_MODE_FORWARD; + else if (!strcmp(mode_str, "backward")) + mode = TRAVERSE_MODE_BACKWARD; + else + return FALSE; + trie_set_traverse_mode(mode); + return TRUE; +} +#undef arg_mode + + +/* trie_traverse_first(+Trie, -Ref) */ +#define arg_trie YAP_ARG1 +#define arg_ref YAP_ARG2 +static int p_trie_traverse_first(void) { + TrData data; + + /* check arg */ + if (!YAP_IsIntTerm(arg_trie)) + return FALSE; + + /* traverse trie */ + if (!(data = trie_traverse_first((TrEntry) YAP_IntOfTerm(arg_trie)))) { + return FALSE; + } + return YAP_Unify(arg_ref, YAP_MkIntTerm((YAP_Int) data)); +} +#undef arg_trie +#undef arg_ref + + +/* trie_traverse_next(+Ref, -Ref) */ +#define arg_cur YAP_ARG1 +#define arg_next YAP_ARG2 +static int p_trie_traverse_next(void) { + TrData data; + + /* check arg */ + if (!YAP_IsIntTerm(arg_cur)) + return FALSE; + + /* traverse trie */ + if (!(data = trie_traverse_next((TrData) YAP_IntOfTerm(arg_cur)))) { + return FALSE; + } + return YAP_Unify(arg_next, YAP_MkIntTerm((YAP_Int) data)); +} +#undef arg_cur +#undef arg_next + + +/* trie_disable_hash */ +static int p_trie_disable_hash(void) { + trie_disable_hash_table(); + return TRUE; +} + + +/* trie_enable_hash */ +static int p_trie_enable_hash(void) { + trie_enable_hash_table(); + return TRUE; +} + + +/* trie_to_list(+Trie, -List) */ +#define arg_trie YAP_ARG1 +#define arg_list YAP_ARG2 +static int p_trie_to_list(void) { + YAP_Term list; + + /* check arg */ + if (!YAP_IsIntTerm(arg_trie)) + return FALSE; + + /* get list from trie */ + list = trie_to_list((TrEntry) YAP_IntOfTerm(arg_trie)); + return YAP_Unify(arg_list, list); +} +#undef arg_trie +#undef arg_list + + +/* trie_depth_breadth(+Trie, -DepthBreadthTrie, -FinalLabel, +OptimizationLevel, +StartCounter, -EndCounter) */ +#define arg_trie YAP_ARG1 +#define arg_db_trie YAP_ARG2 +#define arg_final_label YAP_ARG3 +#define arg_opt_level YAP_ARG4 +#define arg_start_counter YAP_ARG5 +#define arg_end_counter YAP_ARG6 +static int p_trie_depth_breadth(void) { + /* get depth breadth trie */ + if (!YAP_IsIntTerm(arg_opt_level)) + return FALSE; + if (!YAP_IsIntTerm(arg_start_counter)) + return FALSE; + YAP_Int End; + YAP_Term t = trie_depth_breadth((TrEntry) YAP_IntOfTerm(arg_trie), (TrEntry) YAP_IntOfTerm(arg_db_trie), YAP_IntOfTerm(arg_opt_level), YAP_IntOfTerm(arg_start_counter), &End); + int a = YAP_Unify(t, arg_final_label); + a = a && YAP_Unify(YAP_MkIntTerm(End), arg_end_counter); + return a; +} +#undef arg_trie +#undef arg_db_trie +#undef arg_final_label +#undef arg_opt_level +#undef arg_start_counter +#undef arg_end_counter + + +/* trie_get_depth_breadth_reduction_entry(-Entry) */ +#define arg_entry YAP_ARG1 +static int p_trie_get_depth_breadth_reduction_current_data(void) { + TrData data = trie_get_depth_breadth_reduction_current_data(); + if (data) + return YAP_Unify(arg_entry, YAP_MkIntTerm((YAP_Int) data)); + return FALSE; +} +#undef arg_entry + + +db_trie_opt_level *opt_level; + +/* trie_get_depth_breadth_reduction_opt_level_count(?OptLevel, -Count) */ +#define arg_opt_level YAP_ARG1 +#define arg_count YAP_ARG2 +static int p_trie_get_db_opt_level_count_init(void) { + if (YAP_IsIntTerm(arg_opt_level)) { + if (YAP_IntOfTerm(arg_opt_level) > 0 && YAP_IntOfTerm(arg_opt_level) < 4) { + if (YAP_Unify(arg_count, YAP_MkIntTerm(trie_get_db_opt_level_count(YAP_IntOfTerm(arg_opt_level))))) { + YAP_cut_succeed(); + return TRUE; + } else { + YAP_cut_fail(); + return FALSE; + } + } else { + YAP_cut_fail(); + return FALSE; + } + } + if (YAP_IsVarTerm(arg_opt_level)) { + YAP_PRESERVE_DATA(opt_level, db_trie_opt_level); + opt_level->value = YAP_MkIntTerm(1); + if (YAP_Unify(arg_opt_level, opt_level->value)) { + return YAP_Unify(arg_count, YAP_MkIntTerm(trie_get_db_opt_level_count(YAP_IntOfTerm(arg_opt_level)))); + } + YAP_cut_fail(); + return FALSE; + } + YAP_cut_fail(); + return FALSE; +} +#undef arg_opt_level +#undef arg_count + + +/* trie_get_depth_breadth_reduction_opt_level_count(?OptLevel, -Count) */ +#define arg_opt_level YAP_ARG1 +#define arg_count YAP_ARG2 +static int p_trie_get_db_opt_level_count_cont(void) { + YAP_PRESERVED_DATA(opt_level, db_trie_opt_level); + opt_level->value = YAP_MkIntTerm(YAP_IntOfTerm(opt_level->value) + 1); + if (YAP_IntOfTerm(opt_level->value) < 4) { + if (YAP_Unify(arg_opt_level, opt_level->value)); + return YAP_Unify(arg_count, YAP_MkIntTerm(trie_get_db_opt_level_count(YAP_IntOfTerm(arg_opt_level)))); + YAP_cut_fail(); + return FALSE; + } else { + YAP_cut_fail(); + return FALSE; + } +} +#undef arg_opt_level +#undef arg_count + + +/* trie_replace_nested_trie(+Trie, +NestedTrieID, +ReplaceTerm) */ +#define arg_trie YAP_ARG1 +#define arg_nested_id YAP_ARG2 +#define arg_term YAP_ARG3 +static int p_trie_replace_nested_trie(void) { + if (!YAP_IsIntTerm(arg_nested_id)) + return FALSE; + if (!YAP_IsNonVarTerm(arg_term)) + return FALSE; + trie_replace_nested_trie((TrEntry) YAP_IntOfTerm(arg_trie), YAP_IntOfTerm(arg_nested_id), arg_term); + return TRUE; +} +#undef arg_trie +#undef arg_nested_id +#undef arg_term + + +/* trie_db_opt_min_prefix(?MinPrefix) */ +#define arg_min_prefix YAP_ARG1 +static int p_trie_db_opt_min_prefix(void) { + YAP_Int min_prefix; + + /* get mode */ + if (YAP_IsVarTerm(arg_min_prefix)) { + min_prefix = trie_get_db_opt_min_prefix(); + return YAP_Unify(arg_min_prefix, YAP_MkIntTerm(min_prefix)); + } + + /* set mode */ + if (YAP_IsIntTerm(arg_min_prefix)) { + min_prefix = YAP_IntOfTerm(arg_min_prefix); + if (min_prefix > 1) { + trie_set_db_opt_min_prefix(min_prefix); + return TRUE; + } + } + return FALSE; +} +#undef min_prefix From 5e84c38efeb1631abadac7ca7c27a90acb539199 Mon Sep 17 00:00:00 2001 From: Theo Date: Mon, 19 Jul 2010 12:06:39 +0100 Subject: [PATCH 3/3] fixed trie warnings --- library/tries/core_tries.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/library/tries/core_tries.c b/library/tries/core_tries.c index 59248403b..e7fa6acad 100644 --- a/library/tries/core_tries.c +++ b/library/tries/core_tries.c @@ -329,7 +329,7 @@ TrNode core_trie_put_entry(TrEngine engine, TrNode node, YAP_Term entry, YAP_Int } /* reset var terms */ while (STACK_NOT_EMPTY(stack_vars++, stack_vars_base)) { - POP_DOWN(stack_vars); + (void) POP_DOWN(stack_vars); *((YAP_Term *)*stack_vars) = *stack_vars; } if (depth) @@ -347,7 +347,7 @@ TrNode core_trie_check_entry(TrNode node, YAP_Term entry) { node = check_entry(node, entry); /* reset var terms */ while (STACK_NOT_EMPTY(stack_vars++, stack_vars_base)) { - POP_DOWN(stack_vars); + (void) POP_DOWN(stack_vars); *((YAP_Term *)*stack_vars) = *stack_vars; } return node; @@ -473,14 +473,15 @@ TrNode core_trie_load(TrEngine engine, FILE *file, void (*load_function)(TrNode, TrNode node; char version[15]; fpos_t curpos; + int n; - fscanf(file, "%14s", version); + n = fscanf(file, "%14s", version); if (fgetpos(file, &curpos)) return NULL; if (!strcmp(version, "BEGIN_TRIE_v2")) { fseek(file, -11, SEEK_END); - fscanf(file, "%s", version); + n = fscanf(file, "%s", version); if (strcmp(version, "END_TRIE_v2")) { fprintf(stderr, "******************************************\n"); fprintf(stderr, " Tries core module: trie file corrupted\n"); @@ -492,7 +493,7 @@ TrNode core_trie_load(TrEngine engine, FILE *file, void (*load_function)(TrNode, CURRENT_LOAD_VERSION = 2; } else if (!strcmp(version, "BEGIN_TRIE")) { fseek(file, -8, SEEK_END); - fscanf(file, "%s", version); + n = fscanf(file, "%s", version); if (strcmp(version, "END_TRIE")) { fprintf(stderr, "******************************************\n"); fprintf(stderr, " Tries core module: trie file corrupted\n"); @@ -1377,6 +1378,7 @@ static void traverse_and_load(TrNode parent, FILE *file) { TrHash hash = NULL; YAP_Term t; + int n; if (!fscanf(file, "%lu", &t)) { MARK_AS_LEAF_TRIE_NODE(parent); @@ -1389,16 +1391,16 @@ void traverse_and_load(TrNode parent, FILE *file) { if (t == HASH_SAVE_MARK) { /* alloc a new trie hash */ int num_buckets; - fscanf(file, "%d", &num_buckets); + n = fscanf(file, "%d", &num_buckets); new_trie_hash(hash, 0, num_buckets); TrNode_child(parent) = (TrNode) hash; - fscanf(file, "%lu", &t); + n = fscanf(file, "%lu", &t); } do { TrNode child; if (t == ATOM_SAVE_MARK) { int index; - fscanf(file, "%d", &index); + n = fscanf(file, "%d", &index); if (index > CURRENT_INDEX) { char atom[1000]; if (CURRENT_LOAD_VERSION == 2) { @@ -1409,7 +1411,7 @@ void traverse_and_load(TrNode parent, FILE *file) { *ptr++ = ch; *ptr = '\0'; } else if (CURRENT_LOAD_VERSION == 1) { - fscanf(file, "%s", atom); + n = fscanf(file, "%s", atom); } CURRENT_INDEX = index; if (CURRENT_INDEX == CURRENT_AUXILIARY_TERM_STACK_SIZE) @@ -1419,11 +1421,11 @@ void traverse_and_load(TrNode parent, FILE *file) { t = AUXILIARY_TERM_STACK[index]; } else if (t == FUNCTOR_SAVE_MARK) { int index; - fscanf(file, "%d", &index); + n = fscanf(file, "%d", &index); if (index > CURRENT_INDEX) { char atom[1000]; int arity; - fscanf(file, "%s %d", atom, &arity); + n = fscanf(file, "%s %d", atom, &arity); CURRENT_INDEX = index; if (CURRENT_INDEX == CURRENT_AUXILIARY_TERM_STACK_SIZE) expand_auxiliary_term_stack(); @@ -1431,7 +1433,7 @@ void traverse_and_load(TrNode parent, FILE *file) { } t = AUXILIARY_TERM_STACK[index]; } else if (t == FLOAT_SAVE_MARK) - fscanf(file, "%lu", &t); + n = fscanf(file, "%lu", &t); child = trie_node_insert(parent, t, hash); traverse_and_load(child, file); } while (fscanf(file, "%lu", &t));