end_of_file. % ============================== % Simple MT Prolog Server % ============================== :-dynamic(socket_in/1). :-dynamic(socket_out/1). :-dynamic(serve_connection/0). :-assert(prolog_file_type('P', prolog)). :- style_check(-singleton). :- style_check(-discontiguous). was_style_check(_):- set_prolog_flag(double_quotes,codes). was_indexed(_). :- was_style_check(-atom). :- was_style_check(-string). :- use_module(library(shell)). :- use_module(library(shlib)). :- use_module(library(url)). :- use_module(library(quintus)). %:-set_prolog_flag(unknown,fail). %:-set_prolog_flag(unknown,warn). swi_server(Port):- current_prolog_flag(arch,'i386-win32'),!, tcp_socket(ServerSocket), please_tcp_bind(ServerSocket, Port), tcp_listen(ServerSocket, 655), repeat, tcp_open_socket(ServerSocket, AcceptFd, _Useless), tcp_accept(AcceptFd, ClientSocket, _PeerIP), work_on_client_socket('main',ClientSocket), fail. swi_server(Port):- thread_create(swi_server_thread(Port),_,[]). please_tcp_bind(ServerSocket, Port):- catch((tcp_bind(ServerSocket, Port),writeFmt(user_error,'\nOS gave me port ~w. \n',[Port])),error(E,_),(writeFmt('\nWaiting for OS to release port ~w. \n(sleeping 4 secs becasue "~w")\n',[Port,E]),sleep(4),please_tcp_bind(ServerSocket, Port))). swi_server_thread(Port):- tcp_socket(ServerSocket), (tcp_setopt(ServerSocket, reuseaddr) -> true; writeFmt(user_error,'You need to install the thread-safe version of socket.so (The prolog server may have bugs)\n',[])), please_tcp_bind(ServerSocket, Port), tcp_listen(ServerSocket, 655), repeat, once(work_on_server_socket(ServerSocket)), fail. win32_dispatch(AcceptFd) :- % Non Multit Version sleep(0.1), tcp_accept(AcceptFd, Socket, _PeerIP), writeq(_PeerIP),nl, handle_the_socket(Socket,In, Out), !, win32_dispatch(AcceptFd). work_on_server_socket(ServerSocket):- tcp_open_socket(ServerSocket, AcceptFd, _Useless), tcp_accept(AcceptFd, ClientSocket, _PeerIP), work_on_client_socket_mt(ClientSocket). work_on_client_socket_mt(ClientSocket):- threads, thread_create(( thread_self(Self), mutex_create(Id), mutex_lock(Id),!, with_mutex(Id,work_on_client_socket(Self,ClientSocket)), mutex_unlock_all, thread_exit(complete) ),_,[detatch(true)]). work_on_client_socket_single(ClientSocket):- work_on_client_socket(single,ClientSocket). work_on_client_socket(Self,ClientSocket):- tcp_open_socket(ClientSocket, In, Out),!, writeFmt(user_error,'% thread="~w" input="~w" output="~w" \n',[Self,In,Out]), flush_output(user_error), handle_the_socket(ClientSocket,In, Out). handle_the_socket(ClientSocket,In, Out):- catch(thread_self(ID),_,ID=err), asserta(socket_in(ID,In)), asserta(socket_out(ID,Out)), catch(service_telnet_request(ID,In,Out),E,writeq(service_one_client(E))), retractAllProlog(socket_in(ID,_)), retractAllProlog(socket_out(ID,_)), ignore(( catch(flush_output(Out),_,true), catch(tcp_close_socket(ClientSocket),_,true) )). service_telnet_request(Self,In,Out):- writeFmt(Out,'\n\n',[Self]), flush_output(Out), once(( catch(read_term(In,CMD,[variable_names(Vars)]),_, (writeFmt(Out,'\n',[]),flush_output(Out))) )), getCputime(Start), invoke_cmd(Self,Out,CMD,Vars), statistics(cputime,End), Elapsed is End - Start, writeFmt(Out,'\n\n',[Elapsed]), catch(flush_output(Out),_,true). invoke_cmd(Self,Out,CMD,Vars):- tell(Out), retractAllProlog(answer_yes(Self)), catch(CMD,Err,(writeFmt('',[Err]),!,fail)), assert(answer_yes(Self)), write_swi_vars_proc(Out,Vars), fail. invoke_cmd(Self,Out,_,_):- (retract(answer_yes(Self)) -> writeFmt(Out,'\n',[]) ; writeFmt(Out,'\n',[])),!. write_swi_vars_proc(Out,[]):-!. write_swi_vars_proc(Out,Vars):- write(Out,''), write_swi_vars(Out,Vars), writeFmt(Out,'\n',[]). write_swi_vars(Out,[]):-!. write_swi_vars(Out,[Term|REST]):- !,Term=..[_,N,V], writeFmt(Out,'~q',[N,V]), write_swi_vars(Out,REST). call_as(UserToken,initialize):-term_to_atom(UserToken,ModuleName),assert(ModuleName:usertoken(UserToken)),assert(user:username(UserToken)),!. call_as(UserToken,load_file(Filename)):-term_to_atom(UserToken,ModuleName),ModuleName:ensure_loaded(Filename),!. call_as(UserToken,terminate):-term_to_atom(UserToken,ModuleName),terminate_the(ModuleName),!,retract(user:username(ModuleName)). call_as(UserToken,Goal):-term_to_atom(UserToken,ModuleName),ModuleName:Goal. call_all(Goal):- user:username(UserToken), once(call_as(UserToken,Goal)),fail. call_all(Goal):-!. terminate_modules(UserContraint):- user:username(UserContraint), once(call_as(UserToken,terminate)),fail. terminate_modules(UserContraint):-!. terminate_the(ModuleName):- current_predicate(_,ModuleName:Q), not(predicate_property(Q,built_in)), functor(Q,F,A), ModuleName:abolish(F/A), fail. terminate_the(_ModuleName):-!. serve_me:-repeat,once(serve_connection),retract(is_leaving). goodbye:-saveSigmaCache,assert(is_leaving). serve_connection(Id):- (socket_in(Id,In)), (socket_out(Id,Out)), service_telnet_request(Id,In,Out). serve_connection:- (socket_in(In)), (socket_out(Out)), service_telnet_request(In,Out). use_additional_context(P/N):-use_additional_context(P/N,'user'). use_additional_context(P/N,Add):- not(ground(P/N)),!, writeFmt(user_error,'Instanciation Error in use_additional_context/1-2.\n',[]),fail. use_additional_context(P/N,Add):- context_module(Module), dynamic(Module:P/N), length(Args,N), CallerPrototype=..[P|Args], Prototype=..[P|Args], assert((Add:CallerPrototype:- Module:Prototype)),!. subcontext(user,_). :-dynamic(context_skolem/2). :-dynamic(user:context_dag_db/2). link_module_parent(NewParent):-context_module(Me),link_module_parent(Me,NewParent). link_module_parent(Child,Parent):-not(ground((Child,Parent))),!,writeFmt(user_error,'Error: Arguments are not sufficiently Instanciated ~q \n',[link_module_parent(Child,Parent)]),!,fail. link_module_parent(Child,Parent):-retractAllProlog(user:context_dag_db(Child,Parent)),!,assert(user:context_dag_db(Child,Parent)). remove_module_parent(OldParent):-context_module(Me),remove_module_parent(Me,OldParent). remove_module_parent(Child,Parent):-retractAllProlog(user:context_dag_db(Child,Parent)),!. context_dag(User,Parent):- user:context_dag_db(User,Parent). context_dag(User,Grandparent):- user:context_dag_db(User,Parent), context_dag(Parent,Grandparent). load_file_into_module(File,PublicName):-expand_file_name(File,[Name]),!, open(Name,'read',Stream),!, repeat, once(handle_stream(Stream)), at_end_of_stream(Stream),!,close(Stream). handle_stream(Stream):- catch(read_term(Stream,X,[syntax_errors(true),module(PublicName),term_positon('$stream_position'(CharIndex,LineNum,Line,Pos))]),E,true), warn_call(catch(process_read(PublicName,X),E,writeFmt(user_error,'~q\n',[E]))),flush_output(user_error),!. warn_call(X):-X,!. warm_call(X):-writeFmt(user_error,'WARNING: Prdicate failed ~q \n',[X]),!. process_read(PublicName,':-'(include(File))):-!. %,load_file_into_module(File,PublicName). process_read(PublicName,':-'(X)):-!,PublicName:X. process_read(PublicName,(X)):-!,assert(PublicName:X). call_as(UserToken,initialize):-term_to_atom(UserToken,ModuleName),assert(ModuleName:usertoken(UserToken)),assert(user:username(UserToken)),!. call_as(UserToken,load_file(Filename)):-term_to_atom(UserToken,ModuleName),load_file_into_module(Filename,ModuleName). call_as(UserToken,terminate):-term_to_atom(UserToken,ModuleName),terminate_the(ModuleName),!,retract(user:username(ModuleName)). call_as(UserToken,Goal):-term_to_atom(UserToken,ModuleName),run_under(Goal,ModuleName). run_under(true,User):-!. run_under(Goal,User):-run_under_only(Goal,User). run_under(Goal,User):- context_dag(User,Parent), clause(Parent:Goal,Precons), run_under(Precons,User). run_under_only(true,User):-!. run_under_only(current:B,User) :- !,User:B. run_under_only(_:Goal,User):- predicate_property(Goal,built_in),!,run_special(Goal,User). run_under_only(U:B,User) :- User \==U ,!,run_under(B,U). run_under_only(U:B,User) :- !,User==U,run_under_only(B,User). run_under_only(Goal,User):- predicate_property(Goal,built_in),!,run_special(Goal,User). run_under_only(Goal,User):- clause(User:Goal,Precons), run_under_only(Precons,User). run_under_only(user:Goal,User):- clause(user:Goal,Precons), run_under_only(Precons,user). % this could be circumvented if the user expicitly loaded his/her own library predicates. run_under_only(Goal,User):-functor(Goal,F,A),index(F,A,_,File),once(use_module(library(File))),!,User:Goal. run_special(B,User) :- cutin(B,B1,B2),!, run_under(B1,User),!, run_under(B2,User). run_special(A -> B,User) :- !, run_under(A,User) -> run_under(B,User). /* run_special(A*-> B,User) :- !, run_under(A,User) *-> run_under(B,User). */ run_special((Goal1,Goal2),User):-!, run_under(Goal1,User), run_under(Goal2,User). run_special((Goal1;Goal2),User):-!, run_under(Goal1,User); run_under(Goal2,User). run_special(findall(Vars,Goal,List),User):-!, findall(User,run_under(Goal,User),List). run_special(bagof(Vars,Goal,List),User):-!, bagof(User,run_under(Goal,User),List). run_special(setof(Vars,Goal,List),User):-!, setof(User,run_under(Goal,User),List). run_special(call(Goal),User):-!, setof(User,run_under(Goal,User),List). run_special(once(Goal),User):-!, run_under(Goal,User),!. run_special(ignore(Goal),User):- ignore(run_under(Goal,User)). run_special(not(Goal),User):- not(run_under(Goal,User)). run_special((Goal),User):- User:Goal. cutin(!,!,true) :- !. cutin((!,B),!,B) :- !. cutin((A,!),(A,!),true) :- !. cutin((A,B),(A,As),Bs) :- cutin(B,As,Bs). :-dynamic(user:username/1). user:username(default). % This predicate Calls goal and returns Length answers begining with Start. % Also this can keep infinate chains from taking place. call_number_of(Goal,Start,Length):- End is Start + Length -1, context_module(Ctx), flag(Ctx,_,2),!, Goal, flag(Ctx,F,F+1), StartEnd,!);true). % given this program q(X):-member(X,[a,b,c,d,e,f,g,h,i,j,k,l]). % ============================== % Sending a File back to server % ============================== insert_file_to_stream(O,Filename):- safe_file_open(Filename,'r',Input), putchar_stdout(O,Input). putchar_stdout(O,Input):-at_end_of_stream(Input),close(Input),!. putchar_stdout(O,Input):-get_code(Input,Char),put(O,Char),!,putchar_stdout(O,Input). % Not part of program below basic_facts:- call_as(joe,assert(has(dog))), call_as(joesSister,assert(has(rat))), call_as(joesMom,assert(has(cat))), call_as(joesDad,assert(has(tiger))), call_as(joesGrandpa,assert(keeps(bees))), call_as(user,assert(( has(A):-keeps(A) )) ). /* by putting in 'user' This means the it becomes module_transparent meaning you do not need to use module_transparent/1 or dynamic/1 now. This means all contexts (modules) inherit user automatically. They also of course inherit if you link_module_parent(child,Parent) */ build_family_tree:- link_module_parent(joe,joesMom), link_module_parent(joe,joesDad), link_module_parent(joesDad,joesGrandpa), link_module_parent(joesSister,joesMom), link_module_parent(joesSister,joesDad). removed_dad:- remove_module_parent(joe,joesDad).