Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file swipl.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287(*
SWIPL-OCaml
Copyright (C) 2021 Kiran Gopinathan
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*)moduleRaw=Rawletmodule_sep=lazy(Raw.Functor.functor_(Raw.Atom.atom":")2)letconjunction=lazy(Raw.Functor.functor_(Raw.Atom.atom",")2)letdisjunction=lazy(Raw.Functor.functor_(Raw.Atom.atom";")2)letapply=lazy(Raw.Functor.functor_(Raw.Atom.atom"apply")2)letcall1=lazy(Raw.Functor.functor_(Raw.Atom.atom"call")1)typety=[`Atom|`Blob|`Bool|`Dict|`Float|`Integer|`ListPair|`Nil|`Rational|`String|`Term|`Variable]typectx=Raw.ForeignFrame.toptiontypequery=Raw.Query.qidtypemodule_=Raw.Module.t[@@derivingeq,ord]letmodule_str=Raw.Module.new_module(Raw.Atom.atomstr)typefn=Raw.Functor.t[@@derivingeq,ord]typeatom=Raw.Atom.t[@@derivingeq,ord]typet=|TermofRaw.Term.t|AtomofRaw.Atom.t|AppofRaw.Module.toption*Raw.Functor.t*tlist|Conjunctionoft*t|Disjunctionoft*t[@@derivingeq,ord]letcreate_term(_ctx:ctx)=Raw.Term.new_ref()letcreate_terms(_ctx:ctx)n=Raw.Term.new_refsnletof_termterm=Termtermletencode_stringctxstr=lett=create_termctxinassert(Raw.Term.put_string_charststr);tletencode_listctxls=letrecloopresult=function|[]->assert(Raw.Term.put_nilresult);result|h::t->letresult=loopresulttinassert(Raw.Term.cons_listresulthresult);resultinloop(create_termctx)lsletarray_of_listctxargs=letlength=List.lengthargsiniflength=0thenRaw.Term.Array.emptyelsebeginletterms=create_termsctxlengthinList.iteri(funindterm->assert(Raw.Term.put_term(Raw.Term.Array.gettermsind)term))args;termsendletatomctxv=letresult=create_termctxinRaw.Term.put_atomresultv;resultletapp2ctxfnarg1arg2=letresult=create_termctxinassert(Raw.Term.cons_functor2resultfnarg1arg2);resultletappctxfnargs=letresult=create_termctxinletargs=array_of_listctxargsinassert(Raw.Term.cons_functorresultfnargs);resultletrecto_termctx=function|Termt->t|App(None,fn,args)->appctxfn(List.map(to_termctx)args)|App(Somemodule_,fn,args)->letfn=letlazysep=module_sepinletmodule_=Raw.Module.module_namemodule_inletfn=Raw.Functor.namefninapp2ctxsep(atomctxmodule_)(atomctxfn)inletargs=List.map(to_termctx)argsinletargs=encode_listctxargsinletlazyapply=applyinapp2ctxapplyfnargs|Conjunction(l,r)->letlazyconjunction=conjunctioninletl=to_termctxlinletr=to_termctxrinapp2ctxconjunctionlr|Disjunction(l,r)->letlazydisjunction=disjunctioninletl=to_termctxlinletr=to_termctxrinapp2ctxdisjunctionlr|Atoma->atomctxaletevalctx=letflags=Raw.Q.(normal+ext_status+pass_exception)infunction|Termt->letlazycall=call1inletpred=Raw.Predicate.predcallinRaw.Query.open_query~flagspred(array_of_listctx[t])|App(module_,fn,args)->letpred=Raw.Predicate.pred?module_fninletargs=array_of_listctx(List.map(to_termctx)args)inRaw.Query.open_query?module_~flagspredargs|Atoma->letfn=Raw.Functor.functor_a0inletpred=Raw.Predicate.predfninRaw.Query.open_query~flagspredRaw.Term.Array.empty|Conjunction(l,r)->letlazyconjunction=conjunctioninletconjunction=Raw.Predicate.predconjunctioninRaw.Query.open_query~flagsconjunction(array_of_listctx[to_termctxl;to_termctxr])|Disjunction(l,r)->letlazydisjunction=disjunctioninletdisjunction=Raw.Predicate.preddisjunctioninRaw.Query.open_query~flagsdisjunction(array_of_listctx[to_termctxl;to_termctxr])letinitialise()=Raw.initialise()letwith_ctxf=letframe=Raw.ForeignFrame.open_frame()inletres=f(Someframe)inRaw.ForeignFrame.close_frameframe;resletshowt=with_ctx(functx->to_termctxt|>Raw.Term.get_chars)|>Option.value~default:"None"letppfmtt=Format.pp_print_stringfmt(showt)letfreshctx=of_term(create_termctx)moduleSyntax=structlet(/@)fnx=Raw.Functor.functor_(Raw.Atom.atomfn)xlet(!)x=Atom(Raw.Atom.atomx)letapp?module_fnargs=App(module_,fn,args)let(&&)lr=Conjunction(l,r)let(||)lr=Disjunction(l,r)endletfold_solutionsfnquery=letany_seen=reffalseinletrecloop()=matchRaw.Query.next_solutionquerywith|Raw.Query.Result.Booltrue->any_seen:=true;beginmatchfn`Solutionwith|Some`Close->assert(Raw.Query.close_queryquery)|Some`Cut->assert(Raw.Query.cut_queryquery)|None->loop()end|Raw.Query.Result.Boolfalse->assert(Raw.Query.close_queryquery)|Raw.Query.Result.Last->any_seen:=true;beginmatchfn`Lastwith|Some`Close->assert(Raw.Query.close_queryquery)|Some`Cut->assert(Raw.Query.cut_queryquery)|None->assert(Raw.Query.close_queryquery)end|Raw.Query.Result.Exception->matchRaw.Exception.exnquerywith|None->assert(Raw.Query.close_queryquery)|Someexn->ignore@@begintryfn(`Exception(Termexn))withe->(Raw.Exception.clear_exn();raisee)end;Raw.Exception.clear_exn();assert(Raw.Query.close_queryquery)inbegintryloop()with|e->assert(Raw.Query.close_queryquery);raiseeend;!any_seenletiter_solutions?(on_error=fun_->())queryfn=fold_solutions(function|`Exceptione->on_errore;None|_->fn();None)queryletfirst_solutionquery=fold_solutions(function|`Exceptione->failwith("Prolog query raised exception: "^showe)|`Last->Some`Cut|`Solution->Some`Cut)queryletlast_solutionquery=fold_solutions(function|`Exceptione->failwith("Prolog query raised exception"^showe)|`Last->Some`Cut|`Solution->None)queryletcallctxt=letquery=evalctxtinignore@@first_solutionqueryletextract_listctxterm=letterm=to_termctxterminletrecloopterm=ifRaw.Term.get_niltermthen[]elselethd=create_termctxinlettl=create_termctxinassert(Raw.Term.get_listtermhdtl);(of_termhd)::(looptl)inlooptermletatomt=Raw.Atom.atomtletextract_atomctxterm=Raw.Term.get_atom(to_termctxterm)|>Option.getletshow_atomatom=Raw.Atom.charsatomletpp_atomfmtatom=Format.pp_print_stringfmt(show_atomatom)letextract_boolctxterm=Raw.Term.get_bool(to_termctxterm)|>Option.getletextract_intctxterm=Raw.Term.get_integer(to_termctxterm)|>Option.getletextract_floatctxterm=Raw.Term.get_float(to_termctxterm)|>Option.getletextract_stringctxterm=Raw.Term.get_string_chars(to_termctxterm)|>Option.getletextract_functorctxterm=let(name,arity)=Raw.Term.get_name_arity(to_termctxterm)|>Option.getinletrecloopaccind=ifind<aritythenletarg=create_termctxinassert(Raw.Term.get_arg(ind+1)(to_termctxterm)arg);loop((of_termarg)::acc)(ind+1)elseList.revaccin(name,loop[]0)lettypeof=function|Termt->Raw.Term.term_typet|Atom_->`Atom|App(_,_,_)|Conjunction(_,_)|Disjunction(_,_)->`Termletencode_listctxargs=of_term(List.map(to_termctx)args|>encode_listctx)letencode_stringctxstr=of_term(encode_stringctxstr)letload_sourcetxt=letuser=lazySyntax.(!"user")inletopen_string=lazySyntax.("open_string"/@2)inletload_files=lazySyntax.("load_files"/@2)inletstream=lazySyntax.("stream"/@1)inletopen_stringtxtout=Syntax.(app(Lazy.forceopen_string)[txt;out])inletload_filesintopts=Syntax.(app(Lazy.forceload_files)[int;opts])inletstreamout=Syntax.(app(Lazy.forcestream)[out])inletopen_sourcectxsrc=letout=freshctxinSyntax.(open_string(encode_stringctxsrc)out&&load_files(Lazy.forceuser)(encode_listctx[streamout]))inwith_ctx(functx->callctx(open_sourcectxtxt))