Files
mercury/compiler/mode_info.m
Fergus Henderson 81f9959dc3 Fix the handling of error message contexts for mode errors
Estimated hours taken: 4

compiler/{mode_errors.m,mode_info.m,modes.m,unique_modes.m}:
	Fix the handling of error message contexts for mode errors
	so that it does say `in call to predicate foo/2' when it
	means `in call to function foo/1'.
1996-05-26 08:01:09 +00:00

625 lines
22 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 1995 University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
% File: mode_info.m.
% Main author: fjh.
% This file defines the mode_info data structure, which is used to hold
% the information we need during mode analysis.
%-----------------------------------------------------------------------------%
:- module mode_info.
:- interface.
:- import_module hlds_module, hlds_pred, hlds_goal, hlds_data.
:- import_module map, list, varset, set.
:- interface.
:- type delay_info. % defined in delay_info.m
:- type mode_error_info. % defined in mode_errors.m
% The mode_info data structure and access predicates.
% XXX `side' is not used
:- type mode_context
---> call(
pred_id, % pred name / arity
int % argument number
)
; higher_order_call(
pred_or_func, % is it call/N (higher-order pred call)
% or apply/N (higher-order func call)?
int % argument number
)
; unify(
unify_context, % original source of the unification
side % LHS or RHS
)
/**** Not yet used
; unify_arg(
unify_context,
side,
cons_id,
int
)
****/
; uninitialized.
:- type side ---> left ; right.
:- type call_context
---> unify(unify_context)
; call(pred_id)
; higher_order_call(pred_or_func).
:- type mode_info.
:- pred mode_info_init(io__state, module_info, pred_id, proc_id,
term__context, set(var), instmap, mode_info).
:- mode mode_info_init(di, in, in, in, in, in, in, mode_info_uo) is det.
:- pred mode_info_get_io_state(mode_info, io__state).
:- mode mode_info_get_io_state(mode_info_get_io_state, uo) is det.
:- pred mode_info_set_io_state(mode_info, io__state, mode_info).
:- mode mode_info_set_io_state(mode_info_set_io_state, di, mode_info_uo) is det.
:- pred mode_info_get_module_info(mode_info, module_info).
:- mode mode_info_get_module_info(mode_info_ui, out) is det.
:- pred mode_info_set_module_info(mode_info, module_info, mode_info).
:- mode mode_info_set_module_info(mode_info_di, in, mode_info_uo) is det.
:- pred mode_info_get_preds(mode_info, pred_table).
:- mode mode_info_get_preds(mode_info_ui, out) is det.
:- pred mode_info_get_modes(mode_info, mode_table).
:- mode mode_info_get_modes(mode_info_ui, out) is det.
:- pred mode_info_get_insts(mode_info, inst_table).
:- mode mode_info_get_insts(mode_info_ui, out) is det.
:- pred mode_info_get_predid(mode_info, pred_id).
:- mode mode_info_get_predid(mode_info_ui, out) is det.
:- pred mode_info_get_procid(mode_info, proc_id).
:- mode mode_info_get_procid(mode_info_ui, out) is det.
:- pred mode_info_get_context(mode_info, term__context).
:- mode mode_info_get_context(mode_info_ui, out) is det.
:- pred mode_info_set_context(term__context, mode_info, mode_info).
:- mode mode_info_set_context(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_get_mode_context(mode_info, mode_context).
:- mode mode_info_get_mode_context(mode_info_ui, out) is det.
:- pred mode_info_set_mode_context(mode_context, mode_info, mode_info).
:- mode mode_info_set_mode_context(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_set_call_context(call_context, mode_info, mode_info).
:- mode mode_info_set_call_context(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_set_call_arg_context(int, mode_info, mode_info).
:- mode mode_info_set_call_arg_context(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_unset_call_context(mode_info, mode_info).
:- mode mode_info_unset_call_context(mode_info_di, mode_info_uo) is det.
:- pred mode_info_get_instmap(mode_info, instmap).
:- mode mode_info_get_instmap(mode_info_ui, out) is det.
:- pred mode_info_dcg_get_instmap(instmap, mode_info, mode_info).
:- mode mode_info_dcg_get_instmap(out, mode_info_di, mode_info_uo) is det.
:- pred mode_info_set_instmap(instmap, mode_info, mode_info).
:- mode mode_info_set_instmap(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_get_locked_vars(mode_info, list(set(var))).
:- mode mode_info_get_locked_vars(mode_info_ui, out) is det.
:- pred mode_info_set_locked_vars(mode_info, list(set(var)), mode_info).
:- mode mode_info_set_locked_vars(mode_info_di, in, mode_info_uo) is det.
:- pred mode_info_get_errors(mode_info, list(mode_error_info)).
:- mode mode_info_get_errors(mode_info_ui, out) is det.
:- pred mode_info_get_num_errors(mode_info, int).
:- mode mode_info_get_num_errors(mode_info_ui, out) is det.
:- pred mode_info_set_errors(list(mode_error_info), mode_info, mode_info).
:- mode mode_info_set_errors(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_add_live_vars(set(var), mode_info, mode_info).
:- mode mode_info_add_live_vars(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_remove_live_vars(set(var), mode_info, mode_info).
:- mode mode_info_remove_live_vars(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_var_list_is_live(list(var), mode_info, list(is_live)).
:- mode mode_info_var_list_is_live(in, mode_info_ui, out) is det.
:- pred mode_info_var_is_live(mode_info, var, is_live).
:- mode mode_info_var_is_live(mode_info_ui, in, out) is det.
:- pred mode_info_var_is_nondet_live(mode_info, var, is_live).
:- mode mode_info_var_is_nondet_live(mode_info_ui, in, out) is det.
:- pred mode_info_get_liveness(mode_info, set(var)).
:- mode mode_info_get_liveness(mode_info_ui, out) is det.
:- pred mode_info_get_liveness_2(list(set(var)), set(var), set(var)).
:- mode mode_info_get_liveness_2(in, in, out) is det.
:- pred mode_info_get_varset(mode_info, varset).
:- mode mode_info_get_varset(mode_info_ui, out) is det.
:- pred mode_info_set_varset(varset, mode_info, mode_info).
:- mode mode_info_set_varset(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_get_instvarset(mode_info, varset).
:- mode mode_info_get_instvarset(mode_info_ui, out) is det.
:- pred mode_info_get_var_types(mode_info, map(var,type)).
:- mode mode_info_get_var_types(mode_info_ui, out) is det.
:- pred mode_info_set_var_types(map(var, type), mode_info, mode_info).
:- mode mode_info_set_var_types(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_get_types_of_vars(mode_info, list(var), list(type)).
:- mode mode_info_get_types_of_vars(mode_info_ui, in, out) is det.
:- pred mode_info_lock_vars(set(var), mode_info, mode_info).
:- mode mode_info_lock_vars(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_unlock_vars(set(var), mode_info, mode_info).
:- mode mode_info_unlock_vars(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_var_is_locked(mode_info, var).
:- mode mode_info_var_is_locked(mode_info_ui, in) is semidet.
:- pred mode_info_var_is_locked_2(list(set(var)), var).
:- mode mode_info_var_is_locked_2(in, in) is semidet.
:- pred mode_info_get_delay_info(mode_info, delay_info).
:- mode mode_info_get_delay_info(mode_info_no_io, out) is det.
:- pred mode_info_set_delay_info(delay_info, mode_info, mode_info).
:- mode mode_info_set_delay_info(in, mode_info_di, mode_info_uo) is det.
:- pred mode_info_get_nondet_live_vars(mode_info, list(set(var))).
:- mode mode_info_get_nondet_live_vars(mode_info_no_io, out) is det.
:- pred mode_info_set_nondet_live_vars(list(set(var)), mode_info, mode_info).
:- mode mode_info_set_nondet_live_vars(in, mode_info_di, mode_info_uo) is det.
/*
:- inst uniq_mode_info = bound_unique(
mode_info(
unique,
ground, ground, ground,
ground, ground, ground, ground,
ground, ground, ground, ground,
ground, ground
)
).
*/
:- inst uniq_mode_info = ground.
:- mode mode_info_uo :: free -> uniq_mode_info.
:- mode mode_info_ui :: uniq_mode_info -> uniq_mode_info.
:- mode mode_info_di :: uniq_mode_info -> dead.
% Some fiddly modes used when we want to extract
% the io_state from a mode_info struct and then put it back again.
/*
:- inst mode_info_no_io = bound_unique(
mode_info(
dead, ground, ground, ground,
ground, ground, ground, ground,
ground, ground, ground, ground,
ground, ground
)
).
*/
:- inst mode_info_no_io = ground.
:- mode mode_info_get_io_state :: uniq_mode_info -> mode_info_no_io.
:- mode mode_info_no_io :: mode_info_no_io -> mode_info_no_io.
:- mode mode_info_set_io_state :: mode_info_no_io -> dead.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module delay_info, mode_errors, prog_data.
:- import_module require.
:- type mode_info
---> mode_info(
io__state,
module_info,
pred_id, % The pred we are checking
proc_id, % The mode which we are checking
varset, % The variables in the current proc
map(var, type), % The types of the variables
term__context, % The line number of the subgoal we
% are currently checking
mode_context, % A description of where in the
% goal the error occurred
instmap, % The current instantiatedness
% of the variables
list(set(var)), % The "locked" variables,
% i.e. variables which cannot be
% further instantiated inside a
% negated context
delay_info, % info about delayed goals
list(mode_error_info),
% The mode errors found
list(set(var)), % The live variables,
% i.e. those variables which may be referenced again on forward
% execution or after shallow backtracking. (By shallow
% backtracking, I mean semidet backtracking in a negation,
% if-then-else, or semidet disjunction within the current
% predicate.)
list(set(var)) % The nondet-live variables,
% i.e. those variables which may be referenced again after deep
% backtracking TO THE CURRENT EXECUTION POINT. These are the
% variables which need to be made mostly_unique rather than
% unique when we get to a nondet disjunction or a nondet call.
% We do not include variables which may be referenced again
% after backtracking to a point EARLIER THAN the current
% execution point, since those variables will *already* have
% been marked as mostly_unique rather than unique.)
).
% The normal inst of a mode_info struct: ground, with
% the io_state and the struct itself unique, but with
% multiple references allowed for the other parts.
%-----------------------------------------------------------------------------%
% Initialize the mode_info
mode_info_init(IOState, ModuleInfo, PredId, ProcId, Context, LiveVars,
InstMapping0, ModeInfo) :-
mode_context_init(ModeContext),
LockedVars = [],
delay_info__init(DelayInfo),
ErrorList = [],
% look up the varset and var types
module_info_preds(ModuleInfo, Preds),
map__lookup(Preds, PredId, PredInfo),
pred_info_procedures(PredInfo, Procs),
map__lookup(Procs, ProcId, ProcInfo),
proc_info_variables(ProcInfo, VarSet),
proc_info_vartypes(ProcInfo, VarTypes),
LiveVarsList = [LiveVars],
NondetLiveVarsList = [LiveVars],
ModeInfo = mode_info(
IOState, ModuleInfo, PredId, ProcId, VarSet, VarTypes,
Context, ModeContext,
InstMapping0, LockedVars, DelayInfo, ErrorList,
LiveVarsList, NondetLiveVarsList
).
%-----------------------------------------------------------------------------%
% Lots of very boring access predicates.
mode_info_get_io_state(mode_info(IOState0,_,_,_,_,_,_,_,_,_,_,_,_,_),
IOState) :-
% XXX
copy(IOState0, IOState).
%-----------------------------------------------------------------------------%
mode_info_set_io_state( mode_info(_,B,C,D,E,F,G,H,I,J,K,L,M,N), IOState0,
mode_info(IOState,B,C,D,E,F,G,H,I,J,K,L,M,N)) :-
% XXX
copy(IOState0, IOState).
%-----------------------------------------------------------------------------%
mode_info_get_module_info(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_),
ModuleInfo).
%-----------------------------------------------------------------------------%
mode_info_set_module_info(mode_info(A,_,C,D,E,F,G,H,I,J,K,L,M,N), ModuleInfo,
mode_info(A,ModuleInfo,C,D,E,F,G,H,I,J,K,L,M,N)).
%-----------------------------------------------------------------------------%
mode_info_get_preds(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_), Preds) :-
module_info_preds(ModuleInfo, Preds).
%-----------------------------------------------------------------------------%
mode_info_get_modes(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_), Modes) :-
module_info_modes(ModuleInfo, Modes).
%-----------------------------------------------------------------------------%
mode_info_get_insts(mode_info(_,ModuleInfo,_,_,_,_,_,_,_,_,_,_,_,_), Insts) :-
module_info_insts(ModuleInfo, Insts).
%-----------------------------------------------------------------------------%
mode_info_get_predid(mode_info(_,_,PredId,_,_,_,_,_,_,_,_,_,_,_), PredId).
%-----------------------------------------------------------------------------%
mode_info_get_procid(mode_info(_,_,_,ProcId,_,_,_,_,_,_,_,_,_,_), ProcId).
%-----------------------------------------------------------------------------%
mode_info_get_varset(mode_info(_,_,_,_,VarSet,_,_,_,_,_,_,_,_,_), VarSet).
%-----------------------------------------------------------------------------%
mode_info_set_varset(VarSet, mode_info(A,B,C,D,_,F,G,H,I,J,K,L,M,N),
mode_info(A,B,C,D,VarSet,F,G,H,I,J,K,L,M,N)).
%-----------------------------------------------------------------------------%
mode_info_get_var_types(mode_info(_,_,_,_,_,VarTypes,_,_,_,_,_,_,_,_),
VarTypes).
%-----------------------------------------------------------------------------%
mode_info_set_var_types(VarTypes, mode_info(A,B,C,D,E,_,G,H,I,J,K,L,M,N),
mode_info(A,B,C,D,E,VarTypes,G,H,I,J,K,L,M,N)).
%-----------------------------------------------------------------------------%
mode_info_get_context(mode_info(_,_,_,_,_,_,Context,_,_,_,_,_,_,_), Context).
%-----------------------------------------------------------------------------%
mode_info_set_context(Context, mode_info(A,B,C,D,E,F,_,H,I,J,K,L,M,N),
mode_info(A,B,C,D,E,F,Context,H,I,J,K,L,M,N)).
%-----------------------------------------------------------------------------%
mode_info_get_mode_context(mode_info(_,_,_,_,_,_,_,ModeContext,_,_,_,_,_,_),
ModeContext).
%-----------------------------------------------------------------------------%
mode_info_set_mode_context(ModeContext, mode_info(A,B,C,D,E,F,G,_,I,J,K,L,M,N),
mode_info(A,B,C,D,E,F,G,ModeContext,I,J,K,L,M,N)).
%-----------------------------------------------------------------------------%
mode_info_set_call_context(unify(UnifyContext)) -->
mode_info_set_mode_context(unify(UnifyContext, left)).
mode_info_set_call_context(call(PredId)) -->
mode_info_set_mode_context(call(PredId, 0)).
mode_info_set_call_context(higher_order_call(PredOrFunc)) -->
mode_info_set_mode_context(higher_order_call(PredOrFunc, 0)).
mode_info_set_call_arg_context(ArgNum, ModeInfo0, ModeInfo) :-
mode_info_get_mode_context(ModeInfo0, ModeContext0),
( ModeContext0 = call(PredId, _) ->
mode_info_set_mode_context(call(PredId, ArgNum),
ModeInfo0, ModeInfo)
; ModeContext0 = higher_order_call(PredOrFunc, _) ->
mode_info_set_mode_context(
higher_order_call(PredOrFunc, ArgNum),
ModeInfo0, ModeInfo)
;
error("mode_info_set_call_arg_context")
).
mode_info_unset_call_context -->
mode_info_set_mode_context(uninitialized).
%-----------------------------------------------------------------------------%
mode_info_get_instmap(mode_info(_,_,_,_,_,_,_,_,InstMap,_,_,_,_,_), InstMap).
% mode_info_dcg_get_instmap/3 is the same as mode_info_get_instmap/2
% except that it's easier to use inside a DCG.
mode_info_dcg_get_instmap(InstMap, ModeInfo, ModeInfo) :-
mode_info_get_instmap(ModeInfo, InstMap).
%-----------------------------------------------------------------------------%
mode_info_set_instmap( InstMap,
mode_info(A,B,C,D,E,F,G,H,InstMap0,J,DelayInfo0,L,M,N),
mode_info(A,B,C,D,E,F,G,H,InstMap,J,DelayInfo,L,M,N)) :-
( InstMap = unreachable, InstMap0 \= unreachable ->
delay_info__bind_all_vars(DelayInfo0, DelayInfo)
;
DelayInfo = DelayInfo0
).
%-----------------------------------------------------------------------------%
mode_info_get_locked_vars(mode_info(_,_,_,_,_,_,_,_,_,LockedVars,_,_,_,_),
LockedVars).
%-----------------------------------------------------------------------------%
mode_info_set_locked_vars( mode_info(A,B,C,D,E,F,G,H,I,_,K,L,M,N), LockedVars,
mode_info(A,B,C,D,E,F,G,H,I,LockedVars,K,L,M,N)).
%-----------------------------------------------------------------------------%
mode_info_get_errors(mode_info(_,_,_,_,_,_,_,_,_,_,_,Errors,_,_), Errors).
%-----------------------------------------------------------------------------%
mode_info_get_num_errors(mode_info(_,_,_,_,_,_,_,_,_,_,_,Errors,_,_), NumErrors)
:-
list__length(Errors, NumErrors).
%-----------------------------------------------------------------------------%
mode_info_set_errors( Errors, mode_info(A,B,C,D,E,F,G,H,I,J,K,_,M,N),
mode_info(A,B,C,D,E,F,G,H,I,J,K,Errors,M,N)).
%-----------------------------------------------------------------------------%
% We keep track of the live variables and the nondet-live variables
% a bag, represented as a list of sets of vars.
% This allows us to easily add and remove sets of variables.
% It's probably not maximally efficient.
% Add a set of vars to the bag of live vars and
% the bag of nondet-live vars.
mode_info_add_live_vars(NewLiveVars,
mode_info(A,B,C,D,E,F,G,H,I,J,K,L,LiveVars0,NondetLiveVars0),
mode_info(A,B,C,D,E,F,G,H,I,J,K,L,LiveVars,NondetLiveVars)) :-
LiveVars = [NewLiveVars | LiveVars0],
NondetLiveVars = [NewLiveVars | NondetLiveVars0].
% Remove a set of vars from the bag of live vars and
% the bag of nondet-live vars.
mode_info_remove_live_vars(OldLiveVars, ModeInfo0, ModeInfo) :-
ModeInfo0 = mode_info(A,B,C,D,E,F,G,H,I,J,K,L,
LiveVars0, NondetLiveVars0),
ModeInfo1 = mode_info(A,B,C,D,E,F,G,H,I,J,K,L,
LiveVars, NondetLiveVars),
(
list__delete_first(LiveVars0, OldLiveVars, LiveVars1),
list__delete_first(NondetLiveVars0, OldLiveVars,
NondetLiveVars1)
->
LiveVars = LiveVars1,
NondetLiveVars = NondetLiveVars1
;
error("mode_info_remove_live_vars: failed")
),
% when a variable becomes dead, we may be able to wake
% up a goal which is waiting on that variable
set__to_sorted_list(OldLiveVars, VarList),
mode_info_get_delay_info(ModeInfo1, DelayInfo0),
delay_info__bind_var_list(VarList, DelayInfo0, DelayInfo),
mode_info_set_delay_info(DelayInfo, ModeInfo1, ModeInfo).
% Check whether a list of variables are live or not
mode_info_var_list_is_live([], _, []).
mode_info_var_list_is_live([Var | Vars], ModeInfo, [Live | Lives]) :-
mode_info_var_is_live(ModeInfo, Var, Live),
mode_info_var_list_is_live(Vars, ModeInfo, Lives).
% Check whether a variable is live or not
mode_info_var_is_live(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,LiveVarsList,_), Var,
Result) :-
(
% some [LiveVars]
list__member(LiveVars, LiveVarsList),
set__member(Var, LiveVars)
->
Result = live
;
Result = dead
).
% Check whether a variable is nondet_live or not.
mode_info_var_is_nondet_live(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,_,
NondetLiveVarsList), Var, Result) :-
(
% some [LiveVars]
list__member(LiveVars, NondetLiveVarsList),
set__member(Var, LiveVars)
->
Result = live
;
Result = dead
).
mode_info_get_liveness(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,LiveVarsList,_),
LiveVars) :-
set__init(LiveVars0),
mode_info_get_liveness_2(LiveVarsList, LiveVars0, LiveVars).
mode_info_get_liveness_2([], LiveVars, LiveVars).
mode_info_get_liveness_2([LiveVarsSet | LiveVarsList], LiveVars0, LiveVars) :-
set__union(LiveVars0, LiveVarsSet, LiveVars1),
mode_info_get_liveness_2(LiveVarsList, LiveVars1, LiveVars).
%-----------------------------------------------------------------------------%
% Since we don't yet handle polymorphic modes, the inst varset
% is always empty.
mode_info_get_instvarset(_ModeInfo, InstVarSet) :-
varset__init(InstVarSet).
mode_info_get_types_of_vars(ModeInfo, Vars, TypesOfVars) :-
mode_info_get_var_types(ModeInfo, VarTypes),
map__apply_to_list(Vars, VarTypes, TypesOfVars).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
% The locked variables are stored as a stack
% of sets of variables. A variable is locked if it is
% a member of any of the sets. To lock a set of vars, we just
% push them on the stack, and to unlock a set of vars, we just
% pop them off the stack. The stack is implemented as a list.
mode_info_lock_vars(Vars, ModeInfo0, ModeInfo) :-
mode_info_get_locked_vars(ModeInfo0, LockedVars),
mode_info_set_locked_vars(ModeInfo0, [Vars | LockedVars], ModeInfo).
mode_info_unlock_vars(_, ModeInfo0, ModeInfo) :-
mode_info_get_locked_vars(ModeInfo0, LockedVars0),
( LockedVars0 = [_ | LockedVars1] ->
LockedVars = LockedVars1
;
error("mode_info_unlock_vars: stack is empty")
),
mode_info_set_locked_vars(ModeInfo0, LockedVars, ModeInfo).
mode_info_var_is_locked(ModeInfo, Var) :-
mode_info_get_locked_vars(ModeInfo, LockedVarsList),
mode_info_var_is_locked_2(LockedVarsList, Var).
mode_info_var_is_locked_2([Set | Sets], Var) :-
(
set__member(Var, Set)
->
true
;
mode_info_var_is_locked_2(Sets, Var)
).
mode_info_get_delay_info(mode_info(_,_,_,_,_,_,_,_,_,_,DelayInfo,_,_,_),
DelayInfo).
mode_info_set_delay_info(DelayInfo, mode_info(A,B,C,D,E,F,G,H,I,J,_,L,M,N),
mode_info(A,B,C,D,E,F,G,H,I,J,DelayInfo,L,M,N)).
mode_info_get_nondet_live_vars(mode_info(_,_,_,_,_,_,_,_,_,_,_,_,_,
NondetLiveVars), NondetLiveVars).
mode_info_set_nondet_live_vars(NondetLiveVars,
mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,_),
mode_info(A,B,C,D,E,F,G,H,I,J,K,L,M,NondetLiveVars)).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%