⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oaa.pl

📁 SRI international 发布的OAA框架软件
💻 PL
📖 第 1 页 / 共 5 页
字号:

% We'll always have exactly one oaa_solvables fact.  Note that application
% code should NOT include a declaration or clause for oaa_solvables/1.
oaa_solvables([]).


%*****************************************************************************
% Initialization and connection functions
%*****************************************************************************

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% name:    oaa_SetupCommunication
% purpose: Establishes default communications connections for a client agent
%  inputs:
%  remarks:
%   - If oaa_listen argument is given, opens a listener socket, so the client
%     can handle requests by direct connection.
%   - Attempts to connect to facilitator at address indicated by oaa_connect
%     or default_facilitator parameter in command line, environment
%     variable, or setup file (see com_Connect, in com_tcp.pl).
%   - com_Connect (which see) provides some retry options.
%   - FAILS if connection to the facilitator cannot be established, and
%     prints a simple error message.
%   - After performing local initializations, and calling this procedure,
%     the default client agent should also call oaa_MainLoop(true).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
oaa_SetupCommunication(InitialAgentName) :- 
    ( oaa_ResolveVariables([
        [cmd('-oaa_listen',RequestedAddress)],
	[env('OAA_LISTEN', RequestedAddress)],
	[setup(_, oaa_listen, RequestedAddress)]
	]) ->
        % Open the server connection:
	( com:com_ListenAt(client_listener, 
	        [resolve_vars(false)], RequestedAddress, ServerAddress) ->
	    %oaa:icl_fac_id(MyId),
	    %com_AddInfo(fac_listener, [oaa_id(MyId)]),
	    format('Listening at ~p~n~n', [ServerAddress])
	| otherwise ->
	    format('Unable to open a listener connection; continuing without it~n~n', [])
	)
    | otherwise ->
	true
    ),

    ( oaa_Connect(parent, _Address, InitialAgentName, []) ->
        true
    | otherwise ->
        format('Unable to connect to facilitator~n', []),
	( com:com_connection_info(client_listener, _, _, _, connected) ->
	    format('Closing listener at ~p~n~n', [ServerAddress]),
            oaa_Disconnect(client_listener, _)
	| otherwise -> true),
        fail
    ).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   % name:    oaa_Connect(+ConnectionId, ?Address, +InitialAgentName, +Params).
   % purpose: Connect and handshake with the agent listening on Address,
   %          or, if Address is a var, allow com_Connect to find
   %          the address.

oaa_Connect(ConnectionId, Address, InitialAgentName, Params) :-
    com:com_Connect(ConnectionId, Params, Address, ActualCInfo),
    format('Connected to ~p.~n',[ActualCInfo]),
    oaa_handshake(ConnectionId, InitialAgentName, Params).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% name:    oaa_Disconnect
% purpose: Disconnect the given comm link.
%  inputs:
%   - ConnectionId: A symbolic connection Id associated with an open
%       comm link
%   - Params: Not currently used; reserved for future enhancements
%       Params argument of com_Disconnect
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

oaa_Disconnect(ConnectionID, _Params) :-
    com:com_Disconnect(ConnectionID).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% name:    oaa_Register
% purpose: Once a comm link is established, either as a client to a Facilitator
%  or as a server for other agents, oaa_Register will setup and registration
%  information for this agent.
%  inputs:
%   - ConnectionId: the symbolic connection Id (client or server connection)
%   - AgentName: the name of the agent
%   - Solvables: solvable list
%   - Params:
%       unique_name(T_F) [false]: if 'true', instructs the facilitator
%         that this agent should only be registered if no other agents
%         are registered with the same name.
%
%  Exceptions:
%    agent_name_in_use: returned if unique_name(true) is in Params, and
%      another agent with AgentName is already registered.
%
%   The following information is stored about the current connection,
%   accessible through com_GetInfo(ConnectionId, Info):
%
%	oaa_name(Name) 	: the name of the current agent
%	oaa_address(A)	: the address for the agent
%       connection(C)   : system-level communications handle 
%                           (e.g., socket number)
%
%   if connecting as client, these are also available:
%	other_address(A)	: the Facilitator's address
%	other_name(Name)	: the Facilitator's name
%	other_language(L)	: the Facilitator's language
%	other_dialect(D)	: the Facilitator's dialect (quintus, sicstus)
%	other_version(V)	: the Facilitator's agent library version
%
%   In addition, the following predicates are written to parent Facilitator,
%   or locally if the ConnectionId is a server connection:
%
%	agent_host(Address, Name, Host)
%
%   Solvables are also written using oaa_Declare()
%
%   It is possible for an agent to create both server and client connections.
%   If this agent is a facilitator, it's classified as an agent of class "node"
%   (as opposed to a pure client "leaf" or pure server "root").
%   If this agent is a non facilitator (leaf), then its server socket
%   enables it to accept requests by direct connection.  (However, it
%   still is required to be a client of some facilitator.)
%
% examples:
%   % connecting to a Facilitator
%     MySolvables = [do(something)],
%     com_Connect(parent, [], ConnectionRequest, ActualConnection),
%     oaa_Register(parent, my_agent_name, MySolvables, []).
%
%   % connecting as a Facilitator
%     MySolvables = [],
%     com_ListenAt(fac_listener, ConnectionInfo),
%     oaa_Register(fac_listener, root, MySolvables).
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% For connecting to a Facilitator
oaa_Register(ConnectionId, InitialAgentName, Solvables, Params) :-
	% Am I a facilitator or client?
	oaa_type(Type),

        % Four backwards compatibility, we check to see if handshaking
	% has already occurred.  In pre-3.2 (internal version number),
	% handshaking was always performed by oaa_Register.
        ( com:com_GetInfo(ConnectionId, other_name(_)) ->
	    true
	| otherwise ->
	    oaa_handshake(ConnectionId, InitialAgentName, Params)
	),
	oaa_Address(parent, _, MyAddress),
        % get host info
        ( environ('HOST', MyHost) ->
           true
	| otherwise -> true ),
	
	% Do I have a listener Port?
	( Type == facilitator ->
	    oaa_PrimaryAddress(MyListenAddress)
	| otherwise ->
	    ( com:com_GetInfo(client_listener, oaa_address(MyListenAddress)) ->
	        true
            | otherwise -> true )
	),

	% The actual AgentName isn't necessarily the same as InitialAgentName;
	% InitialAgentName may have been overridden by command line arguments
	oaa_Name(AgentName),

        ( ground(MyHost) ->
	    oaa_AddData(agent_host(MyAddress, AgentName, MyHost), 
	                [address(parent)])
        | true),

        ( ground(MyListenAddress) ->
           oaa_AddData(agent_listener(MyAddress, MyListenAddress), 
	               [address(parent)])
        | true),

        % Declare solvables (and post to parent facilitator):
        % Note: OK if Solvables = [].
        oaa_Declare(Solvables, [], [], [if_exists(overwrite)], _),
        
        % check any builtin command-line args actions
        oaa_command_actions.

% For Facilitator serving client agents
% Note: no need to check for oaa_name cmdline argument; facilitator code
% already does that.
oaa_Register(ConnectionId, AgentName, Solvables, _Params) :-
	% succeeds only if exists an open connection for ConnectionId
	%    as created by com_ListenAt()
	com:com_connection_info(ConnectionId, _Protocol, server, _Info, connected),

	oaa_Address(fac_listener, _, MyAddress),
	com:com_AddInfo(ConnectionId, 
	   [oaa_name(AgentName)]),

    	% The fac. records its own agent_data in the same way as its clients'.
        % Note that we can't call oaa_add_data_local until after the solvables
        % have been declared, and we can't declare solvables until we're
        % open - so we have to bootstrap this assertion.
	% IMPORTANT: by special convention, the type for the facilitator
	% is unbound.
        oaa_assertz(
	    agent_data(MyAddress, _Type, open, [], AgentName, []), 
	    MyAddress, _, true),

        % Note: OK if Solvables = [].
        oaa_Declare(Solvables, [], [], [if_exists(overwrite)], _),

        % write host
        ( environ('HOST', MyHost) ->
           oaa_add_data_local(agent_host(MyAddress, AgentName, MyHost),[])
        | true),

        % check any builtin command-line args actions
        oaa_command_actions.
	


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% name:    oaa_ResolveVariables(+VariableList)
% purpose: Tries to instantiate the arguments by looking in the command
%	   line arguments, environment variables, and setup files
%  inputs:
%   - VarList:	A list of lists: the first sublist that completely resolves
%	   provides the value for oaa_ResolveVariables.
% remarks:
%    sublists may contain elements in the following format:
%       env(EnvVar, Val)	: looks for "EnvVar" in environment vars
%	env_int(EnvVar, Val)	: Returns value for EnvVar as an integer
%	cmd(CmdVar, Val)	: looks for "CmdVar <Val>" on command line
%	setup(File,SVar, Val)	: reads SVar from setup file File
% example:
%    resolves host and port by searching first commandline, then environment
%    variables, finally reads setup file.
%
%     oaa_ResolveVariables([
%         [cmd('-oaa_host',Host), cmd('-oaa_port', Port)],
%	  [env('OAA_HOST', Host), env_int('OAA_PORT', Port)],
%	  [setup('setup.pl',oaa_host, Host), 
%	   setup('setup.pl',oaa_port, Port)]
%     ])
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
oaa_ResolveVariables([VarList|_]) :-
	oaa_resolve_variables(VarList), !.
oaa_ResolveVariables([_VarList|Rest]) :-
	oaa_ResolveVariables(Rest).

oaa_resolve_variables([]).

oaa_resolve_variables([env_int(EnvVar, Val)|Rest]) :- !,
	environ(EnvVar, EnvAtom),
	name(EnvAtom, EnvChars),
	number_chars(Val, EnvChars),
	oaa_resolve_variables(Rest).

oaa_resolve_variables([env(EnvVar, Val)|Rest]) :- !,
	environ(EnvVar, ValAtom),
	oaa_parse_cmd_value(ValAtom, Val),
	oaa_resolve_variables(Rest).

oaa_resolve_variables([cmd(CmdVar, Val)|Rest]) :- !,
	% get command line arguments
	unix(argv(ListOfArgs)),
	append(_, [CmdVar, ValAtom|_], ListOfArgs),
	oaa_parse_cmd_value(ValAtom, Val),
	oaa_resolve_variables(Rest).

%% 0-argument command (conceptually equivalent to "-command true")
oaa_resolve_variables([cmd(CmdVar)|Rest]) :- !,
	% get command line arguments
	unix(argv(ListOfArgs)),
	memberchk(CmdVar, ListOfArgs),
	oaa_resolve_variables(Rest).

oaa_resolve_variables([setup(File, SVar, Val)|Rest]) :- !,
	% read setup file to load all values
	oaa_read_setup_file(File),
	Pred =.. [SVar, Val],
        on_exception(_, Pred, fail),
	oaa_resolve_variables(Rest).

oaa_parse_cmd_value(Value, Value) :-
        number(Value), 
	!.
        % This clause is for structures with arguments.
	% We restrict it by checking for '(', because we do NOT want
	% strings such as /tmp/filename to be parsed here.
	% We'll also parse single-quoted atoms here.
oaa_parse_cmd_value(ValAtom, Value) :-
	name(ValAtom, ValChars),
        ( memberchk(0'(, ValChars) ;
          nth0(0, ValChars, 0'') ),
	concat_atom([ValAtom, '.'], StoppedAtom),
	name(StoppedAtom, Chars),
	on_exception(_, 
	    oaa_read_from_chars(Chars, Value),
	    fail),
        !.
%'
oaa_parse_cmd_value(ValAtom, Value) :-
        name(ValAtom, Chars),
	on_exception(_, number_chars(Value, Chars), fail),
	!.
oaa_parse_cmd_value(ValAtom, ValAtom).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% name:    oaa_read_setup_file
% purpose: Finds and loads setup file
% remarks: 
%    Always succeeds.
%    The search path for the setup file is as follows:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -