/* File:      flrdynmod.P
**
** Author(s): Guizhen Yang 
**
** Contact:   flora-users@lists.sourceforge.net
**
** Copyright (C) The Research Foundation of SUNY, 1999-2001
**
** FLORA-2 is free software; you can redistribute it and/or modify it under the
** terms of the GNU Library General Public License as published by the Free
** Software Foundation; either version 2 of the License, or (at your option)
** any later version.
** 
** FLORA-2 is distributed in the hope that it will be useful, but WITHOUT ANY
** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE.  See the GNU Library General Public License for
** more details.
** 
** You should have received a copy of the GNU Library General Public License
** along with FLORA-2; if not, write to the Free Software Foundation,
** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
** 
** 
*/


:- compiler_options([xpp_on]).

#include "flora_terms.flh"
#include "flora_exceptions.flh"


:- import
	flora_check_module_name/1,
	flora_module_predicate/4,
	flora_decode_module_prefix/3
   from flrwrapper.

:- import flora_increment_counter/4 from flrporting.

:- import convert_to_body_literal/2 from flrcanon.

:- import
	flora_temp_protect_call/2,
	flora_temp_unprotect_call/1
    from flrundefined.

:- import
	flora_in_debug_mode/1,
	flora_debug_module_registry/1
   from flrregistry.

:- import flora_error_line/2 from flrprint.

:- import flora_abort/1 from flrutils.


/*********************************************************************
  This file is for the following dynamic module references:
  FLLIBMODLIT and FLLIBMODOBJ.

  FLLIBMODLIT is used when the compiler encounters literal@Variable
  where literal is F-logic or HiLog
  FLLIBMODOBJ is used when compiler finds term@Variable inside a predicate,
  e.g., f(g@V)
*********************************************************************/


/*********************************************************************
  FLLIBMODLIT(+Functor,+Args,+ModuleName)
*********************************************************************/
FLLIBMODLIT(F,Arg,ModuleName) :-
	%% If module is a variable, we must protect the call
	%% from undefinedness checks
	(var(ModuleName) -> ProtectCall = true ; true),
	(var(Arg)
	-> flora_abort([Arg,'@',ModuleName,': Attempt to call uninstantiated literal'])
	; flora_check_module_name(ModuleName),
	    (
	      (
		is_list(Arg), Arg = Args, !, % Term@X
		flora_module_predicate(F,Args,ModuleName,P)
	      ; atom(Arg), !,	% Var@..., Var bound to atom
		( %% if already a hilog predicate -- use it -- Is this case possible??
		    flora_decode_module_prefix(Arg,_,_), Arg = P, !
		%% else construct it
		; flora_module_predicate(WRAP_HILOG,[Arg],ModuleName,P)
		)
	      ; Arg =.. [Funct|Args], !, % Var@..., Var bound to compound
		( %% if already a hilog or flogic predicate -- use it
		    flora_decode_module_prefix(Funct,_,_), Arg = P, !
		%% else construct it
		; flora_module_predicate(Funct,Args,ModuleName,P)
		)
	      )
	    ->
	      %% Protect call P from undefinedness check
	      (nonvar(ProtectCall),
		  flora_in_debug_mode(_),
		  flora_debug_module_registry(ModuleName)
	      -> flora_increment_counter(FLORA_SYMBOL('protect_undef_call'),1,_,Id),
		  flora_temp_protect_call(P,Id)
	      ; Id = 0
	      ),
	      %% Whether P succeeds or fails we must remove the temporary
	      %% skeleton from the set of facts protected from undefinedness
	      %% checking
	      (call(P), (Id > 0 -> flora_temp_unprotect_call(Id) ; true)
	      ; Id > 0, flora_temp_unprotect_call(Id), fail
	      )
	    )
	).


/*********************************************************************
  FLLIBMODOBJ(+Functor,+Args,+ModuleName,-Predicate)
*********************************************************************/
FLLIBMODOBJ(F,Arg,ModuleName,Pout) :-
	(var(Arg)
	-> flora_abort([Arg,'@',ModuleName,': Attempt to query uninstantiated literal'])
	; flora_check_module_name(ModuleName),
	    (
	      ( 
		is_list(Arg), Arg = Args, !, % Term@X
		flora_module_predicate(F,Args,ModuleName,P)
	      ; atom(Arg), !,	% Var@..., Var bound to atom
		( %% if already a hilog predicate -- use it
		    flora_decode_module_prefix(Arg,_,_), Arg = P, !
		%% else construct it
		; flora_module_predicate(WRAP_HILOG,[Arg],ModuleName,P)
		)
	      ; Arg =.. [Funct|Args], !, % Var@..., Var bound to compound
		( %% if already a hilog or flogic predicate -- use it
		    flora_decode_module_prefix(Funct,_,_), Arg = P, !
		%% else construct it
		; flora_module_predicate(Funct,Args,ModuleName,P)
		)
	      )
	    -> true
	    ),
	    convert_to_body_literal(P,Pout)
	).



syntax highlighted by Code2HTML, v. 0.9.1