123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)openPp(*s Definition of a search problem. *)moduletypeSearchProblem=sigtypestatevalbranching:state->statelistvalsuccess:state->boolvalpp:state->Pp.tendmoduleMake=functor(S:SearchProblem)->structtypeposition=intlistletmsg_with_position(p:position)pp=letrecpp_rec=function|[]->mt()|[i]->inti|i::l->pp_recl++str"."++intiinFeedback.msg_debug(h(pp_recp)++pp)(*s Depth first search. *)letrecdepth_firsts=ifS.successsthenselsedepth_first_many(S.branchings)anddepth_first_many=function|[]->raiseNot_found|[s]->depth_firsts|s::l->trydepth_firstswithNot_found->depth_first_manylletdebug_depth_firsts=letrecexploreps=msg_with_positionp(S.pps);ifS.successsthenselseexplore_many1p(S.branchings)andexplore_manyip=function|[]->raiseNot_found|[s]->explore(i::p)s|s::l->tryexplore(i::p)swithNot_found->explore_many(succi)plinexplore[1]s(*s Breadth first search. We use functional FIFOS à la Okasaki. *)type'aqueue='alist*'alistexceptionEmptyletempty=[],[]letpushx(h,t):_queue=(x::h,t)letpop=function|h,x::t->x,(h,t)|h,[]->matchList.revhwithx::t->x,([],t)|[]->raiseEmptyletbreadth_firsts=letrecexploreq=let(s,q')=trypopqwithEmpty->raiseNot_foundinenqueueq'(S.branchings)andenqueueq=function|[]->exploreq|s::l->ifS.successsthenselseenqueue(pushsq)linenqueueempty[s]letdebug_breadth_firsts=letrecexploreq=let((p,s),q')=trypopqwithEmpty->raiseNot_foundinenqueue1pq'(S.branchings)andenqueueipq=function|[]->exploreq|s::l->letps=i::pinmsg_with_positionps(S.pps);ifS.successsthenselseenqueue(succi)p(push(ps,s)q)linenqueue1[]empty[s]end