diff --git a/library/Makefile.in b/library/Makefile.in index 442046a5f..bab726884 100644 --- a/library/Makefile.in +++ b/library/Makefile.in @@ -78,6 +78,7 @@ PROGRAMS= \ $(srcdir)/lam_mpi.yap \ $(srcdir)/ypp.yap \ $(srcdir)/c_alarms.yap \ + $(srcdir)/flags.yap \ $(srcdir)/block_diagram.yap MYDDAS_PROGRAMS= $(srcdir)/MYDDAS/myddas.ypp \ diff --git a/library/flags.yap b/library/flags.yap new file mode 100644 index 000000000..9e4b047e8 --- /dev/null +++ b/library/flags.yap @@ -0,0 +1,561 @@ +%%% -*- Mode: Prolog; -*- + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Flags was developed at Katholieke Universiteit Leuven +% +% Copyright 2010 +% Katholieke Universiteit Leuven +% +% Contributions to this file: +% Author: Theofrastos Mantadelis +% Sugestions: Bernd Gutmann, Paulo Moura +% Version: 0.1 +% Date: 19/11/2010 +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% 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. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +:- module(flags, [flag_define/2, + flag_define/5, + flag_define/7, + flag_set/2, + flag_set/3, + flag_unsafe_set/2, + flag_get/2, + flags_reset/0, + flags_reset/1, + flags_save/1, + flags_load/1, + flag_groups/1, + flag_group_chk/1, + flag_help/0, + flags_print/0, + defined_flag/7]). + +:- use_module(library(lists), [append/3, memberchk/2, member/2]). + +:- style_check(all). +:- yap_flag(unknown, error). + +:- dynamic(['$defined_flag$'/7, '$store_flag_value$'/2]). +:- meta_predicate(flag_define(+, +, +, ?, ?, ?, :)). +:- meta_predicate(flag_define(+, :)). +:- meta_predicate(validate(+, :, ?, +)). +:- multifile(flags_type_definition/3). + +flag_define(FlagName, InputOptions):- + strip_module(InputOptions, Module, UserOptions), + Defaults = [flag_group(general), flag_type(nonvar), default_value(true), description(FlagName), access(read_write), handler(true)], + append(UserOptions, Defaults, Options), + memberchk(flag_group(FlagGroup), Options), + memberchk(flag_type(FlagType), Options), + memberchk(default_value(DefaultValue), Options), + memberchk(description(Description), Options), + memberchk(access(Access), Options), + memberchk(handler(Handler), Options), + flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Module:Handler). + +flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description):- + flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, read_write, true). + +flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, MHandler):- + strip_module(MHandler, Module, Handler), + nonvar(FlagName), + nonvar(FlagGroup), + nonvar(FlagType), + nonvar(Access), + nonvar(Handler), !, + (\+ atom(FlagName) -> + throw(error(type_error(atom, FlagName), message('Flag name needs to be an atom.', flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Module:Handler)))) + ; \+ atom(FlagGroup) -> + throw(error(type_error(atom, FlagGroup), message('Flag group needs to be an atom.', flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Module:Handler)))) + ; \+ flag_type(FlagType) -> + throw(error(domain_error(flag_type, FlagType), message('Unknown flag type.', flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Module:Handler)))) + ; \+ validate_type(FlagType) -> + throw(error(evaluation_error(type_validation), message('Validation of flag type failed, check custom domain.', flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Module:Handler)))) + ; '$defined_flag$'(FlagName, _FlagGroup, _FlagType, _DefaultValue, _Description, _Access, _Handler) -> + throw(error(permission_error(create, flag, FlagName), message('Re-defining a flag is not allowed.', flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Module:Handler)))) + ; \+ memberchk(Access, [read_write, read_only, hidden, hidden_read_only]), + throw(error(domain_error(access, Access), message('Wrong access attribute, available are: read_write, read_only, hidden, hidden_read_only.', flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Module:Handler)))) + ; \+ callable(Handler) -> + throw(error(type_error(callable, Handler), message('Flag handler needs to be callable.', flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Module:Handler)))) + ; + validate(FlagType, Module:Handler, DefaultValue, FlagName), + assertz('$defined_flag$'(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Module:Handler)), + assertz('$store_flag_value$'(FlagName, DefaultValue)), + (Handler == true -> + true + ; + call(Module:Handler, stored, DefaultValue) + ) + ). +flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Handler):- + throw(error(instantiation_error, message('Flag name, group, type, access and handler need to be instantiated.', flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Handler)))). + +flag_groups(FlagGroups):- + all(FlagGroup, ('$defined_flag$'(_FlagName, FlagGroup, _FlagType, _DefaultValue, _Description, Access, _Handler), Access \== hidden, Access \== hidden_read_only), FlagGroups). + +flag_group_chk(FlagGroup):- + nonvar(FlagGroup), + '$defined_flag$'(_FlagName, FlagGroup, _FlagType, _DefaultValue, _Description, _Access, _Handler), !. + +flag_type(Type):- + flags_type_definition(Type, _, _). + +% flags_type_definition(TypeName, TypeHandler, TypeValidator). +flags_type_definition(nonvar, nonvar, true). +flags_type_definition(atom, atom, true). +flags_type_definition(atomic, atomic, true). +flags_type_definition(integer, integer, true). +flags_type_definition(float, float, true). +flags_type_definition(number, number, true). +flags_type_definition(ground, ground, true). +flags_type_definition(compound, compound, true). +flags_type_definition(is_list, is_list, true). +flags_type_definition(callable, callable, true). +flags_type_definition(in_interval(Type, Interval), in_interval(Type, Interval), in_interval(Type, Interval)). +flags_type_definition(integer_in_interval(Interval), in_interval(integer, Interval), in_interval(integer, Interval)). +flags_type_definition(positive_integer, in_interval(integer, (0, (+inf))), true). +flags_type_definition(non_negative_integer, in_interval(integer, ([0], (+inf))), true). +flags_type_definition(negative_integer, in_interval(integer, ((-inf), 0)), true). +flags_type_definition(float_in_interval(Interval), in_interval(float, Interval), in_interval(float, Interval)). +flags_type_definition(positive_float, in_interval(float, (0.0, (+inf))), true). +flags_type_definition(non_negative_float, in_interval(float, ([0.0], (+inf))), true). +flags_type_definition(negative_float, in_interval(float, ((-inf), 0.0)), true). +flags_type_definition(number_in_interval(Interval), in_interval(number, Interval), in_interval(number, Interval)). +flags_type_definition(positive_number, in_interval(number, (0.0, (+inf))), true). +flags_type_definition(non_negative_number, in_interval(number, ([0.0], (+inf))), true). +flags_type_definition(negative_number, in_interval(number, ((-inf), 0.0)), true). +flags_type_definition(in_domain(Domain), in_domain(Domain), in_domain(Domain)). +flags_type_definition(boolean, in_domain([true, false]), true). +flags_type_definition(switch, in_domain([on, off]), true). + +in_domain(Domain):- + ground(Domain), + is_list(Domain). +in_domain(Domain, Value):- + ground(Value), + memberchk(Value, Domain). + +in_interval(Type, Interval):- + is_list(Interval), !, + Interval \== [], + in_interval_conj(Type, Interval). +in_interval(Type, Interval):- + in_interval_single(Type, Interval). + +in_interval_conj(_Type, []). +in_interval_conj(Type, [Interval|Rest]):- + in_interval_single(Type, Interval), + in_interval_conj(Type, Rest). + +in_interval_single(Type, ([Min], [Max])):- + !, call(Type, Min), + call(Type, Max), + Min =< Max. + +in_interval_single(Type, ([Min], Max)):- + !, call(Type, Min), + call(Type, Max), + Min < Max. + +in_interval_single(Type, (Min, [Max])):- + !, call(Type, Min), + call(Type, Max), + Min < Max. + +in_interval_single(Type, (Min, Max)):- + call(Type, Min), + call(Type, Max), + Min < Max, + Max - Min > 0.0. + +in_interval(Type, [Interval|_Rest], Value):- + in_interval(Type, Interval, Value), !. +in_interval(Type, [_Interval|Rest], Value):- + in_interval(Type, Rest, Value). + +in_interval(Type, ([Min], [Max]), Value):- + !, call(Type, Value), + Value >= Min, + Value =< Max. + +in_interval(Type, ([Min], Max), Value):- + !, call(Type, Value), + Value >= Min, + Value < Max. + +in_interval(Type, (Min, [Max]), Value):- + !, call(Type, Value), + Value > Min, + Value =< Max. + +in_interval(Type, (Min, Max), Value):- + call(Type, Value), + Value > Min, + Value < Max. + +validate_type(Type):- + flags_type_definition(Type, _, TypeValidater), + call(TypeValidater). + +validate(FlagType, Handler, Value, FlagName):- + strip_module(Handler, _Module, true), + !, flags_type_definition(FlagType, FlagValidator, _), + (call(FlagValidator, Value) -> + true + ; + throw(error(validation_error(FlagType, Value), message('Validation of value fails.', validate(FlagType, Value, FlagName)))) + ). +validate(FlagType, Handler, Value, FlagName):- + flags_type_definition(FlagType, FlagValidator, _), + ((call(Handler, validating, Value), (call(FlagValidator, Value); call(Handler, validate, Value))) -> + call(Handler, validated, Value) + ; + throw(error(validation_error(FlagType, Value), message('Validation of value fails.', validate(FlagType, Handler, Value, FlagName)))) + ). + +flag_set(FlagName, FlagValue):- + flag_set(FlagName, _OldValue, FlagValue). +flag_set(FlagName, OldValue, FlagValue):- + atom(FlagName), + '$defined_flag$'(FlagName, _FlagGroup, FlagType, _DefaultValue, _Description, Access, Module:Handler), !, + (Access \== read_only, Access \== hidden_read_only -> + validate(FlagType, Module:Handler, FlagValue, FlagName), + retract('$store_flag_value$'(FlagName, OldValue)), + assertz('$store_flag_value$'(FlagName, FlagValue)), + (Handler == true -> + true + ; + call(Module:Handler, stored, FlagValue) + ) + ; + throw(error(permission_error(set, flag, FlagName), message('Setting the flag value is not allowed.',flag_set(FlagName, OldValue, FlagValue)))) + ). +flag_set(FlagName, OldValue, FlagValue):- + throw(error(existence_error(flag, FlagName), message('The flag is not defined.', flag_set(FlagName, OldValue, FlagValue)))). + +flag_unsafe_set(FlagName, FlagValue):- + retract('$store_flag_value$'(FlagName, _)), + assertz('$store_flag_value$'(FlagName, FlagValue)). + +flag_get(FlagName, FlagValue):- + '$store_flag_value$'(FlagName, FlagValue). +flag_get(FlagName, FlagValue):- + \+ '$store_flag_value$'(FlagName, _), + throw(error(existence_error(flag, FlagName), message('The flag is not defined.', flag_get(FlagName, FlagValue)))). + +flags_reset:- + retractall('$store_flag_value$'(_, _)), + '$defined_flag$'(FlagName, _FlagGroup, _FlagType, DefaultValue, _Description, _Access, Module:Handler), + assertz('$store_flag_value$'(FlagName, DefaultValue)), + (Handler == true -> + true + ; + call(Module:Handler, stored, DefaultValue) + ), + fail. +flags_reset. + +flags_reset(FlagGroup):- + '$defined_flag$'(FlagName, FlagGroup, _FlagType, DefaultValue, _Description, _Access, Module:Handler), + retractall('$store_flag_value$'(FlagName, _)), + assertz('$store_flag_value$'(FlagName, DefaultValue)), + (Handler == true -> + true + ; + call(Module:Handler, stored, DefaultValue) + ), + fail. +flags_reset(_). + +flags_save(FileName):- + tell(FileName), + catch(('$store_flag_value$'(FlagName, Value), + write_canonical('$store_flag_value$'(FlagName, Value)), + write('.'), nl), + Exception, clean_and_throw(told, Exception)), + fail. +flags_save(_FileName):- + told. + +flags_load(FileName):- + see(FileName), + catch((read('$store_flag_value$'(FlagName, Value)), + flag_set(FlagName, Value)), + Exception, clean_and_throw(seen, Exception)), + fail. +flags_load(_FileName):- + seen. + +clean_and_throw(Action, Exception):- + Action, + throw(Exception). + +flag_help:- + format('This is a short tutorial for the flags library.~nExported predicates:~n'), + format(' flag_define/5 : defines a new flag without a handler~n'), + format(' flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description)~n'), + format(' flag_define/6 : defines a new flag with a handler~n'), + format(' flag_define(FlagName, FlagGroup, FlagType, DefaultValue, Description, Handler)~n'), + format(' FlagName : the name of the flag~n'), + format(' FlagGroup : the name of the flag group~n'), + format(' FlagType : the type of the flag available types are:~n'), + flag_help_types, + format(' DefaultValue : the default value for the flag~n'), + format(' Description : a flag description~n'), + format(' Handler : a handler~n'), + flags:flag_help_handler, + format(' flag_groups/1 : returns all the flag groups in a list~n'), + format(' flag_group_chk/1 : checks if a group exists~n'), + format(' flag_set/2 : sets the value of a flag~n'), + format(' flag_get/2 : gets the value of a flag~n'), + format(' flag_store/2 : sets the value of a flag ignoring all tests and handlers~n'), + format(' flag_reset/0 : resets all flags to their default value~n'), + format(' flag_reset/1 : resets all flags of a group to their default value~n'), + format(' flag_help/0 : this screen~n'), + format(' flags_print/0 : shows the current flags/values~n'). +flag_help_types:- + flag_type(FlagType), + format(' ~w~n', [FlagType]), + fail. +flag_help_types. + +flag_help_handler:- + format(' Handler important notes:~n'), + format(' Conjuction: external_handler(validating, Value):-...~n'), + format(' Disjunction: external_handler(validate, Value):-...~n'), + format(' After: external_handler(validated, Value):-...~n'), + format(' After set: external_handler(stored, Value):-...~n'), + format(' this is implemented as (validating,(original;validated))~n'), + format(' validating|original|validate|result~n'), + format(' true | true | true | true~n'), + format(' true | true | fail | true~n'), + format(' true | fail | true | true~n'), + format(' true | fail | fail | fail~n'), + format(' fail | true | true | fail~n'), + format(' fail | true | fail | fail~n'), + format(' fail | fail | true | fail~n'), + format(' fail | fail | fail | fail~n'), + format(' Default behaviour is validating->true, validate->fail~n'), + format(' To completly replace original set validate->true~n'), + format(' To add new values to original set validating->true~n'), + format(' To remove values from original set validate->fail~n'), + format(' Example definition with a handler:~n'), + format(' flag_define(myflag, mygroup, in_interval(integer, [(-5, 5),([15],[25])]), 0, description, my_handler).~n'), + format(' my_handler(validate, Value):-Value is 10.~n'), + format(' my_handler(validating, Value).~n'), + format(' my_handler(validated, Value).~n'), + format(' my_handler(stored, Value).~n'), + format(' This has defined a flag that accepts integers (-5,5)v[15,25].~n'), + format(' The handler adds the value 10 in those.~n'). + +flags_print:- + flag_groups(Groups), + forall(member(Group, Groups), flags_print(Group)). +flags_print(Group):- + format(' ~w:~n~w~38+ ~w~19+ ~w~10+ ~w~10+~n', [Group, 'Description', 'Domain', 'Flag', 'Value']), + fail. +flags_print(FlagGroup):- + '$defined_flag$'(FlagName, FlagGroup, FlagType, _DefaultValue, Description, Access, _Handler), + Access \== hidden, Access \== hidden_read_only, + flag_get(FlagName, Value), + format('~w~38+ ~w~19+ ~w~10+ ~q~10+~n', [Description, FlagType, FlagName, Value]), + fail. +flags_print(_). + +defined_flag(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Handler):- + '$defined_flag$'(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Handler), + Access \== hidden, Access \== hidden_read_only. +defined_flag(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Handler):- + nonvar(FlagName), nonvar(FlagGroup), + '$defined_flag$'(FlagName, FlagGroup, FlagType, DefaultValue, Description, Access, Handler). + +