home *** CD-ROM | disk | FTP | other *** search
- /*===================================================================*/
- /*----Linda Arity Prolog Tuple Server and Client Libraries */
- /*---- */
- /*----Written by Geoff Sutcliffe, August 1990 */
- /*===================================================================*/
- /*----Server library */
- /*===================================================================*/
- /*----Start the server, with a goal and its Prolog file */
- server_go(Server_machine,Client_machine_definitions,
- Communication_information):-
- assertz(server_machine__(Server_machine)),
- convert_machine_definitions_to_names__(Client_machine_definitions,
- Client_machines),
- set_up_server_communications__(Server_machine,Client_machines,
- Communication_information),
- !,
- initialise_client_machines__(Client_machines),
- control_service__,
- terminate_client_machines__(Client_machines),
- close_down_server_communications__(Server_machine,Client_machines,
- Communication_information),
- retract_once__(server_machine__(Server_machine)).
-
- server_go(_,_):-
- write('Error : Communications not set up'),
- nl.
- /*-------------------------------------------------------------------*/
- convert_machine_definition_to_names__(Machine_definition,[]):-
- Machine_definition =.. [_,Index],
- Index < 1,
- !.
-
- convert_machine_definition_to_names__(Machine_definition,
- [Machine_definition]):-
- Machine_definition =.. [_,1],
- !.
-
- convert_machine_definition_to_names__(Machine_definition,
- [Machine_definition|Rest_of_names]):-
- Machine_definition =.. [Actual_name,Index],
- Next_index is Index - 1,
- Next_machine_definition =.. [Actual_name,Next_index],
- convert_machine_definition_to_names__(Next_machine_definition,
- Rest_of_names).
- /*-------------------------------------------------------------------*/
- /*----Convert names like bison(3) into bison(0),bison(1),bison(2) */
- convert_machine_definitions_to_names__([],[]).
-
- convert_machine_definitions_to_names__([First_machine_definition|
- Rest_of_machine_definitions],Client_machine_names):-
- convert_machine_definition_to_names__(First_machine_definition,
- First_names),
- convert_machine_definitions_to_names__(Rest_of_machine_definitions,
- Rest_of_names),
- append__(First_names,Rest_of_names,Client_machine_names).
- /*-------------------------------------------------------------------*/
- /*----Get a list of all available machines, in use and not in use */
- get_machines_lists__(Machines_in_use,Machines_not_in_use):-
- findall(Machine_in_use,machine__(Machine_in_use,in_use),
- Machines_in_use),
- findall(Machine_not_in_use,machine__(Machine_not_in_use,
- not_in_use),Machines_not_in_use).
- /*-------------------------------------------------------------------*/
- /*----Repeatedly allow the user to specify a goal and file */
- control_service__:-
- write('Options : "start" client; "exit" : '),
- read(Option),
- Option.
- /*-------------------------------------------------------------------*/
- /*----Do the option chosen by the user in service control */
- start:-
- get_machines_lists__(Machines_in_use,Machines_not_in_use),
- write('In use : '),
- write(Machines_in_use),
- nl,
- write('Free : '),
- write(Machines_not_in_use),
- nl,
- write('Client : '),
- read(Client),
- write('Goal : '),
- read(Goal),
- write('Files : '),
- read(Files),
- server_machine__(Server_machine),
- server_eval__(Server_machine,Client,Goal,Files),
- serve__,
- control_service__.
-
- exit.
- /*-------------------------------------------------------------------*/
- /*----If no machines in use the serving is over */
- serve__:-
- repeat,
- receive_term_from_any_client__(Request),
- do_request__(Request),
- not(machine__(_,in_use)).
- /*-------------------------------------------------------------------*/
- /*----Do a client request by simply evaluating it */
- do_request__(Request):-
- Request,
- !.
-
- /*----If a request fails, then output */
- do_request__(Request):-
- write('Error : '),
- write(Request),
- write(' : failed'),
- nl.
- /*-------------------------------------------------------------------*/
- /*----Start up the client machines by noting their availability */
- initialise_client_machines__([]).
-
- initialise_client_machines__([First_client|Rest_of_clients]):-
- power_up_machine__(First_client),
- assertz(machine__(First_client,not_in_use)),
- initialise_client_machines__(Rest_of_clients).
- /*-------------------------------------------------------------------*/
- /*----Stop client machine by sending them a message to say it's all */
- /*----over, and denoting their availability */
- terminate_client_machines__([]).
-
- terminate_client_machines__([First_client_machine|
- Rest_of_client_machines]):-
- debug_write__('Close : '),
- debug_write__(First_client_machine),
- debug_nl__,
- power_down_machine__(First_client_machine),
- retract_once__(machine__(First_client_machine,not_in_use)),
- terminate_client_machines__(Rest_of_client_machines).
- /*-------------------------------------------------------------------*/
- /*===================================================================*/
- /*----Procedures for doing eval requests
- /*===================================================================*/
- /*----Start a new query in a Prolog file */
- server_eval__(Originating_machine,Machine,Goal,Files):-
- retract_once__(machine__(Machine,not_in_use)),
- !,
- start_client__(Machine),
- assertz(machine__(Machine,in_use)),
- send_term_to_client__(Machine,client_eval__(Machine,Goal,
- Files)),
- debug_write__('Client : '),
- debug_write__(Originating_machine),
- debug_write__(' : starts : '),
- debug_write__(Machine),
- debug_write__(' : '),
- debug_write__(Goal),
- debug_write__(' : '),
- debug_write__(Files),
- debug_nl__.
-
- server_eval__(Originating_machine,Machine,Goal,Files):-
- check_machine_is_in_use__(Machine),
- !,
- note_waiting__(server_eval__(Originating_machine,Machine,Goal,
- Files)),
- debug_write__('Wait : '),
- debug_write__(Machine),
- debug_write__(' : '),
- debug_write__(Goal),
- debug_write__(' : '),
- debug_write__(Files),
- debug_nl__.
-
- server_eval__(Originating_machine,Machine,Goal,Files):-
- write('Error : eval for non-existant machine : '),
- write(Machine),
- nl.
- /*-------------------------------------------------------------------*/
- /*----Check that a requested machine does exist, taking into account */
- /*----under specified machine names. */
- check_machine_is_in_use__(Machine):-
- var(Machine),
- !,
- machine__(_,in_use).
-
- check_machine_is_in_use__(Machine):-
- Machine =.. [Name,Index],
- var(Index),
- !,
- Machine_to_check =.. [Name,_],
- machine__(Machine_to_check,in_use).
-
- check_machine_is_in_use__(Machine):-
- machine__(Machine,in_use).
- /*-------------------------------------------------------------------*/
- /*----Start a new query in a Prolog file, if possible. Return info */
- server_evalp__(Originating_machine,Machine,Goal,Files):-
- retract_once__(machine__(Machine,not_in_use)),
- !,
- assertz(machine__(Machine,in_use)),
- start_client__(Machine),
- send_term_to_client__(Machine,client_eval__(Machine,Goal,
- Files)),
- send_term_to_client__(Originating_machine,Machine),
- debug_write__('Client : '),
- debug_write__(Originating_machine),
- debug_write__(' : starts : '),
- debug_write__(Machine),
- debug_write__(' : '),
- debug_write__(Goal),
- debug_write__(' : '),
- debug_write__(Files),
- debug_nl__.
-
- server_evalp__(Originating_machine,Machine,Goal,Files):-
- send_term_to_client__(Originating_machine,fail),
- debug_write__('Fail : '),
- debug_write__(Machine),
- debug_write__(' : '),
- debug_write__(Goal),
- debug_write__(' : '),
- debug_write__(Files),
- debug_nl__.
- /*-------------------------------------------------------------------*/
- /*----This is executed by the server when the client has completed an*/
- /*----eval */
- end_eval__(Machine):-
- debug_write__('End : '),
- debug_write__(Machine),
- debug_nl__,
- retract_once__(machine__(Machine,in_use)),
- stop_client__(Machine),
- assertz(machine__(Machine,not_in_use)),
- redo_waiting_requests__(machine__(Machine,not_in_use)).
- /*===================================================================*/
- /*----Procedures for out requests */
- /*===================================================================*/
- /*----Execute out, checking for any ins and rds waiting for the tuple*/
- server_out__(Machine,Tuple):-
- do_server_out__(Machine,Tuple),
- redo_waiting_requests__(Tuple).
- /*-------------------------------------------------------------------*/
- /*----This actually puts the tuple in tuple space */
- do_server_out__(Machine,Tuple):-
- assertz(Tuple),
- debug_write__('Added : '),
- debug_write__(Tuple),
- debug_write__(' : from : '),
- debug_write__(Machine),
- debug_nl__.
- /*===================================================================*/
- /*----Procedures for in requests */
- /*===================================================================*/
- /*----Execute in, if not possible then put on waiting queue */
- server_in__(Machine,Tuple):-
- do_server_in__(Machine,Tuple),
- !,
- send_term_to_client__(Machine,Tuple).
-
- server_in__(Machine,Tuple):-
- debug_write__('in wait : '),
- debug_write__(Tuple),
- debug_write__(' : for : '),
- debug_write__(Machine),
- debug_nl__,
- note_waiting__(server_in__(Machine,Tuple)).
- /*-------------------------------------------------------------------*/
- /*----Execute inp, if not possible return fail */
- server_inp__(Machine,Tuple):-
- do_server_in__(Machine,Tuple),
- !,
- send_term_to_client__(Machine,Tuple).
-
- server_inp__(Machine,Tuple):-
- send_term_to_client__(Machine,fail),
- debug_write__('No inp : '),
- debug_write__(Tuple),
- debug_write__(' : for : '),
- debug_write__(Machine),
- debug_nl__.
- /*-------------------------------------------------------------------*/
- /*----This actually gets the tuple out of tuple space */
- do_server_in__(Machine,Tuple):-
- retract_once__(Tuple),
- debug_write__('Removed : '),
- debug_write__(Tuple),
- debug_write__(' : to : '),
- debug_write__(Machine),
- debug_nl__.
- /*===================================================================*/
- /*----Procedures for rd requests */
- /*===================================================================*/
- /*----Execute rd if not possible then put on waiting queue */
- server_rd__(Machine,Tuple):-
- do_server_rd__(Machine,Tuple),
- !,
- send_term_to_client__(Machine,Tuple).
-
- server_rd__(Machine,Tuple):-
- debug_write__('rd wait : '),
- debug_write__(Tuple),
- debug_write__(' : for : '),
- debug_write__(Machine),
- debug_nl__,
- note_waiting__(server_rd__(Machine,Tuple)).
- /*-------------------------------------------------------------------*/
- /*----Execute rdp, if not possible return fail */
- server_rdp__(Machine,Tuple):-
- do_server_rd__(Machine,Tuple),
- !,
- send_term_to_client__(Machine,Tuple).
-
- server_rdp__(Machine,Tuple):-
- send_term_to_client__(Machine,fail),
- debug_write__('No rdp : '),
- debug_write__(Tuple),
- debug_write__(' : for : '),
- debug_write__(Machine),
- debug_nl__.
- /*-------------------------------------------------------------------*/
- /*----Execute rdall, returning the collected tuples */
- server_rdall__(Machine,Tuple,Maximum_replies):-
- findallmax__(Tuple,Tuple,Reply_tuples,Maximum_replies),
- send_term_to_client__(Machine,Reply_tuples).
- /*-------------------------------------------------------------------*/
- /*----This actually checks for the tuple in tuple space */
- do_server_rd__(Machine,Tuple):-
- Tuple,
- debug_write__('Examine : '),
- debug_write__(Tuple),
- debug_write__(' : for : '),
- debug_write__(Machine),
- debug_nl__.
- /*-------------------------------------------------------------------*/
- /*----muProlog fix for tuples that aren't defined */
- traperror(enoproc,_,fail).
- /*===================================================================*/
- /*----Procedures for the waiting queue */
- /*===================================================================*/
- /*-------------------------------------------------------------------*/
- /*----Initial waiting list is empty */
- waiting_list__([]).
- /*-------------------------------------------------------------------*/
- note_waiting__(Request):-
- retract(waiting_list__(List)),
- assertz(waiting_list__([Request|List])).
- /*-------------------------------------------------------------------*/
- redo_waiting_requests__(Outed_tuple):-
- retract(waiting_list__(Waiting_requests)),
- assertz(waiting_list__([])),
- doall__(Waiting_requests).
- /*-------------------------------------------------------------------*/
- doall__([]):-
- !.
-
- doall__([First|Rest]):-
- First,
- doall__(Rest).
- /*===================================================================*/
- /*----Remote i/o procedures */
- /*===================================================================*/
- server_remote_write__(Machine,Term):-
- write(Machine),
- write(' : '),
- write(Term),
- nl.
- /*-------------------------------------------------------------------*/
- /*===================================================================*/
- /*----Client library */
- /*===================================================================*/
- /*----This is for networks that have to have the client machines */
- /*----started manually. */
- client_go(Server_machine,Client_machine,Communication_information):-
- set_up_client_communications__(Server_machine,Client_machine,
- Communication_information),
- !,
- client_machine_loop__,
- close_down_client_communications__(Server_machine,Client_machine,
- Communication_information).
-
- client_go(_,_):-
- write('Error : Communications not set up'),
- nl.
- /*-------------------------------------------------------------------*/
- /*----A manually started machine sits and waits for client_eval__ and*/
- /*----exit__ mesages */
- client_machine_loop__:-
- repeat,
- receive_term_from_server__(Reply),
- Reply,
- Reply == exit__.
- /*-------------------------------------------------------------------*/
- consult_each_file__([]):-
- !.
-
- consult_each_file__([First_file|Rest_of_files]):-
- name(First_file,File_list),
- append__("linda/",File_list,Full_list),
- name(Full_file_path,Full_list),
- consult(Full_file_path),
- consult_each_file__(Rest_of_files).
- /*-------------------------------------------------------------------*/
- /*----This is used to start up a new job on this client. */
- client_eval__(This_machine_name,Goal,Files):-
- assertz(client_machine__(This_machine_name)),
- consult_each_file__(Files),
- Goal,
- !,
- send_request__(end_eval__),
- retract(client_machine__(This_machine_name)).
-
- client_eval__(_,_,_):-
- send_request__(end_eval__),
- retract(client_machine__(This_machine_name)).
- /*-------------------------------------------------------------------*/
- /*----This is used to close down manually started client machines */
- exit__.
- /*-------------------------------------------------------------------*/
- /*===================================================================*/
- /*---Procedures for doing Linda operations */
- /*===================================================================*/
- /*----eval sends a request */
- eval(Machine,Goal,Files):-
- send_request__(server_eval__(Machine,Goal,Files)).
- /*-------------------------------------------------------------------*/
- /*----evalp sends a request */
- evalp(Machine,Goal,Files):-
- send_request__(server_evalp__(Machine,Goal,Files)),
- receive_term_from_server__(Machine).
- /*-------------------------------------------------------------------*/
- /*----out sends a request */
- out(Tuple):-
- send_request__(server_out__(Tuple)).
- /*-------------------------------------------------------------------*/
- /*----in sends a request and reads the reply */
- in(Tuple):-
- send_request__(server_in__(Tuple)),
- receive_term_from_server__(Tuple).
- /*-------------------------------------------------------------------*/
- /*----inp sends a request and reads the reply. The reply may be fail */
- inp(Tuple):-
- send_request__(server_inp__(Tuple)),
- receive_term_from_server__(Tuple).
- /*-------------------------------------------------------------------*/
- /*----rd sends a request and reads the reply */
- rd(Tuple):-
- send_request__(server_rd__(Tuple)),
- receive_term_from_server__(Tuple).
- /*-------------------------------------------------------------------*/
- /*----rdp sends a request and reads the reply. The reply may be fail */
- rdp(Tuple):-
- send_request__(server_rdp__(Tuple)),
- receive_term_from_server__(Tuple).
- /*-------------------------------------------------------------------*/
- /*----rdall sends a request for all tuples. Reply is a list */
- rdall(Tuple,Maximum_replies,Reply_tuples):-
- send_request__(server_rdall__(Tuple,Maximum_replies)),
- receive_term_from_server__(Reply_tuples).
- /*-------------------------------------------------------------------*/
- /*----remote_write asks the server to do output */
- remote_write(Term):-
- send_request__(server_remote_write__(Term)).
- /*-------------------------------------------------------------------*/
- /*----Requests sent from a client to the server */
- send_request__(Request):-
- /*----Stuff this machine's name and index on the front */
- Request =.. [Principle|Arguments],
- member__(Principle,[server_rd__,server_rdp__,server_in__,
- server_inp__,server_eval__,server_evalp__,end_eval__,server_out__,
- server_remote_write__]),
- !,
- client_machine__(Machine),
- Message =.. [Principle,Machine|Arguments],
- send_term_to_server__(Message).
-
- send_request__(Request):-
- send_term_to_server__(Request).
- /*-------------------------------------------------------------------*/
- /*===================================================================*/
- /*----Debugging tools */
- /*===================================================================*/
- debug_write__(Term):-
- debugging__,
- !,
- write(Term).
-
- debug_write__(_).
- /*-------------------------------------------------------------------*/
- debug_nl__:-
- debugging__,
- !,
- nl.
-
- debug_nl__.
- /*-------------------------------------------------------------------*/
- debugging__:-
- fail.
- /*===================================================================*/
- /*----Utilities */
- /*===================================================================*/
- /*-------------------------------------------------------------------*/
- retract_once__(Term):-
- retract(Term),
- !.
- /*-------------------------------------------------------------------*/
- append__([],List,List).
-
- append__([Head|Tail],List,[Head|New_list]):-
- append__(Tail,List,New_list).
- /*-------------------------------------------------------------------*/
- member__(Element,[Element|_]):-
- !.
-
- member__(Element,[_|Tail]):-
- member__(Element,Tail).
- /*-------------------------------------------------------------------*/
- /*----Quick and dirty findall implementation */
- findall(Variable,Goal,_):-
- Goal,
- assertz(findall_result__(Variable)),
- fail.
-
- findall(_,_,List):-
- collectall__(List).
-
- collectall__([First|Rest]):-
- retract(findall_result__(First)),
- !,
- collectall__(Rest).
-
- collectall__([]).
- /*-------------------------------------------------------------------*/
- /*===================================================================*/
- /*----muProlog specific stuff */
- /*===================================================================*/
- /*----Start up for muProlog clients. The interpreter starts after the*/
- /*----save point. The communicator will exec the saved file, thus if */
- /*----any changes are made to this file, linda_go must be re-run to */
- /*----create a new version of the linda file. */
- make_linda:-
- save(linda),
- receive_term_from_server__(client_eval__(Machine,Goal,Files)),
- client_eval__(Machine,Goal,Files),
- exit(0).
- /*-------------------------------------------------------------------*/
- make_new_server_entries(_,1,Entries,Entries):-
- !.
-
- make_new_server_entries(Server_machine_name,Count,
- Rest_of_entries,[First_entry|Rest_of_entries]):-
- New_count is Count - 1,
- First_entry =.. [Server_machine_name,New_count].
- /*-------------------------------------------------------------------*/
- update_server_entry([First_entry|Rest_of_entries],Server_machine_name,
- New_server_entries):-
- First_entry =.. [Server_machine_name,Count],
- !,
- make_new_server_entries(Server_machine_name,Count,
- Rest_of_entries,New_server_entries).
-
- update_server_entry([First_entry|Rest_of_entries],Server_machine_name,
- [First_entry|New_rest_of_entries]):-
- update_server_entry(Rest_of_entries,Server_machine_name,
- New_rest_of_entries).
- /*-------------------------------------------------------------------*/
- make_mugo(Server_machine_name):-
- retract(client_list(Machine_list)),
- update_server_entry(Machine_list,Server_machine_name,
- New_machine_list),
- asserta(client_list(New_machine_list)),
- save(mugo),
- client_list(Client_list),
- server_go(server(1),Client_list,null).
- /*-------------------------------------------------------------------*/
- client_list(
- [bettong(1),bilby(1),bison(1),budgie(1),cricket(1),
- dunnart(1),hawk(1),kowari(1),melomys(1),narbelek(1),ningaui(1),
- numbat(1),planigale(1),potoroo(1),quenda(1),quokka(1),quoll(1),
- tammar(1),wambenger(1),warabi(1),woylie(1)]).
- /*-------------------------------------------------------------------*/
- /*===================================================================*/
- /*----Problem specific stuff */
- /*===================================================================*/
- genetic1(Number_of_transferers,Number_of_breeders,Pool_size,
- Breeds,File_name):-
- /* asserta(debugging__), */
- /* asserta(debugging_net__), */
- server_machine__(Server_machine),
- client_list([First_client|Rest_of_client_list]),
- first_N(Number_of_transferers,Transferers,Rest_of_client_list,
- Other_clients),
- first_N(Number_of_breeders,Breeders,Other_clients,_),
- server_eval__(Server_machine,First_client,
- start_breeding(Transferers,Breeders,Pool_size,Breeds,File_name),
- [genetic1,File_name]),
- serve__,
- control_service__.
- /*-------------------------------------------------------------------*/
- first_N(0,[],Left,Left):-
- !.
-
- first_N(N,[First|Rest],[First|Available],Left):-
- N1 is N - 1,
- first_N(N1,Rest,Available,Left).
- /*-------------------------------------------------------------------*/
- genetic2(Number_of_breeders,Pool_size,Breeds,Youth_advantage,
- File_name):-
- /* asserta(debugging__), */
- /* asserta(debugging_net__), */
- server_machine__(Server_machine),
- client_list([First_client|Rest_of_client_list]),
- first_N(Number_of_breeders,Breeders,Rest_of_client_list,_),
- server_eval__(Server_machine,First_client,
- start_breeding(Breeders,Pool_size,Breeds,Youth_advantage,File_name),
- [genetic2,File_name]),
- serve__,
- control_service__.
- /*-------------------------------------------------------------------*/
-