@@ -2741,29 +2741,37 @@ let repack_goal (gid[@trace]) ~depth program goal =
27412741 { depth ; program ; goal ; gid = gid [@ trace] }
27422742 [@@ inline]
27432743
2744-
2745- (* The activation frames points to the choice point that
2746- cut should backtrack to, i.e. the first one not to be
2747- removed. We call it catto_alts in the code. *)
2748- type frame =
2749- | FNil
2750- | FCons of (* lvl:*) alternative * goal list * frame
2751- and alternative = {
2752- cutto_alts : alternative ;
2753- program : prolog_prog ;
2754- adepth : int ;
2755- agoal_hd : constant ;
2756- ogoal_arg : term ;
2757- ogoal_args : term list ;
2758- agid : UUID .t ; [@ trace]
2759- goals : goal list ;
2760- stack : frame ;
2761- trail : T .trail ;
2762- state : State .t ;
2763- clauses : clause list ;
2764- next : alternative ;
2744+ type goals_crumbles = {
2745+ predicate : constant ;
2746+ fst_arg : term ;
2747+ other_args : term list ;
2748+ brothers : goal list ;
27652749}
2766- let noalts : alternative = Obj. magic 0
2750+
2751+ (* The tree *)
2752+ type continuation = (* the AND part, what to do next *)
2753+ | Done
2754+ | ExitSLGRoot of { heap : unit ; next : continuation ; alts : alternative }
2755+ | TableSolution of unit
2756+ | SolveGoals of { cutto_alts : alternative ; brothers : goal list ; next : continuation }
2757+ and alternative = (* the OR part, what to do if we fail *)
2758+ | Noalts
2759+ | UnblockSLGGenerator of slg_generator (* a branch of the tree that could have been cut *)
2760+ | ExploreAnotherSLDPath of {
2761+ program : prolog_prog ;
2762+ adepth : int ;
2763+ path : goals_crumbles ;
2764+ agid : UUID .t ; [@ trace]
2765+ stack : continuation ;
2766+ trail : T .trail ;
2767+ state : State .t ;
2768+ clauses : clause list ;
2769+ alts : alternative ;
2770+ cutto_alts : alternative ;
2771+ }
2772+ and slg_generator =
2773+ | Root of { root_goal : term ; root_goal_args : int ; clauses : clause list ; }
2774+ | UnexploredBranches of { heap : unit ; alts : alternative }
27672775
27682776(* *****************************************************************************
27692777 Constraint propagation
@@ -3333,7 +3341,7 @@ let pp_candidate ~depth ~k fmt ({ loc } as cl) =
33333341let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x executable -> 'x runtime =
33343342 (* Input to be read as the orl (((p,g)::gs)::next)::alts
33353343 depth >= 0 is the number of variables in the context. *)
3336- let rec run depth p g (gid [@trace ]) gs (next : frame ) alts cutto_alts =
3344+ let rec run depth p g (gid [@trace ]) gs (next : continuation ) alts cutto_alts =
33373345 [% cur_pred (pred_of g)];
33383346 [% trace " run" ~rid begin
33393347
@@ -3405,11 +3413,11 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
34053413 | Const k -> [% spy " user:rule" ~rid ~gid pp_string " backchain" ];
34063414 let clauses = get_clauses depth k g p in
34073415 [% spyl " user:candidates" ~rid ~gid (pp_candidate ~depth ~k ) clauses];
3408- [% tcall backchain depth p (k, C. dummy, [] , gs) (gid[@ trace]) next alts cutto_alts clauses]
3416+ [% tcall backchain depth p { predicate = k; fst_arg = C. dummy; other_args = [] ; brothers = gs} (gid[@ trace]) next alts cutto_alts clauses]
34093417 | App (k ,x ,xs ) -> [% spy " user:rule" ~rid ~gid pp_string " backchain" ];
34103418 let clauses = get_clauses depth k g p in
34113419 [% spyl " user:candidates" ~rid ~gid (pp_candidate ~depth ~k ) clauses];
3412- [% tcall backchain depth p (k, x, xs, gs) (gid[@ trace]) next alts cutto_alts clauses]
3420+ [% tcall backchain depth p { predicate = k; fst_arg = x; other_args = xs; brothers = gs} (gid[@ trace]) next alts cutto_alts clauses]
34133421 | Builtin (c , args ) -> [% spy " user:rule" ~rid ~gid pp_string " builtin" ];
34143422 begin match Constraints. exect_builtin_predicate c ~depth p (gid[@ trace]) args with
34153423 | gs' ->
@@ -3428,15 +3436,15 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
34283436 error " The goal is a flexible term"
34293437 end ]
34303438
3431- (* We pack some arguments into a tuple otherwise we consume too much stack *)
3432- and backchain depth p (k , arg , args_of_g , gs ) (gid [@trace ]) next alts cutto_alts cp = [% trace " select" ~rid begin
3439+ (* We pack some arguments into the goals_crumbles record otherwise we consume too much stack *)
3440+ and backchain depth p ({ predicate = k ; fst_arg = arg ; other_args = args_of_g ; brothers = gs } as g_gs ) (gid [@trace ]) next alts cutto_alts cp = [% trace " select" ~rid begin
34333441 match cp with
34343442 | [] -> [% spy " user:select" ~rid ~gid pp_string " fail" ];
34353443 [% tcall next_alt alts]
34363444 | { depth = c_depth ; mode = c_mode ; args = c_args ; hyps = c_hyps ; vars = c_vars ; loc } :: cs ->
34373445 [% spy " user:select" ~rid ~gid (pp_option Util.CData. pp) (Util. option_map Ast. cloc.Util.CData. cin loc) (ppclause ~depth ~hd: k) { depth = c_depth; mode = c_mode; args = c_args; hyps = c_hyps; vars = c_vars; loc }];
34383446 let old_trail = ! T. trail in
3439- T. last_call := alts == noalts && cs == [] ;
3447+ T. last_call := alts == Noalts && cs == [] ;
34403448 let env = Array. make c_vars C. dummy in
34413449 match
34423450 match c_args with
@@ -3446,21 +3454,21 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
34463454 | [] -> unif ~argsdepth: depth ~matching: false (gid[@ trace]) depth env c_depth arg x && for_all23 ~argsdepth: depth (unif (gid[@ trace])) depth env c_depth args_of_g xs
34473455 | matching :: ms -> unif ~argsdepth: depth ~matching (gid[@ trace]) depth env c_depth arg x && for_all3b3 ~argsdepth: depth (unif (gid[@ trace])) depth env c_depth args_of_g xs ms false
34483456 with
3449- | false -> T. undo old_trail () ; [% tcall backchain depth p (k, arg, args_of_g, gs) (gid[@ trace]) next alts cutto_alts cs]
3457+ | false -> T. undo old_trail () ; [% tcall backchain depth p g_gs (gid[@ trace]) next alts cutto_alts cs]
34503458 | true ->
34513459 let oldalts = alts in
34523460 let alts = if cs = [] then alts else
3453- { program = p; adepth = depth; agoal_hd = k; ogoal_arg = arg; ogoal_args = args_of_g; agid = gid[@ trace]; goals = gs ; stack = next;
3461+ ExploreAnotherSLDPath { program = p; adepth = depth; path = g_gs; agid = gid[@ trace]; stack = next;
34543462 trail = old_trail;
34553463 state = ! CS. state;
3456- clauses = cs; cutto_alts = cutto_alts ; next = alts} in
3464+ clauses = cs; cutto_alts = cutto_alts ; alts} in
34573465 begin match c_hyps with
34583466 | [] ->
34593467 begin match gs with
34603468 | [] -> [% tcall pop_andl alts next cutto_alts]
34613469 | { depth ; program; goal; gid = gid [@ trace] } :: gs -> [% tcall run depth program goal (gid[@ trace]) gs next alts cutto_alts] end
34623470 | h ::hs ->
3463- let next = if gs = [] then next else FCons ( cutto_alts,gs, next) in
3471+ let next = if gs = [] then next else SolveGoals { cutto_alts; brothers = gs; next } in
34643472 let h = move ~argsdepth: depth ~from: c_depth ~to_: depth env h in
34653473 let hs =
34663474 List. map (fun x ->
@@ -3472,14 +3480,18 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
34723480
34733481 and cut (gid [@trace ]) gs next (alts [@trace ]) cutto_alts =
34743482 [% spy " user:cut" ~rid ~gid (fun fmt alts ->
3475- let rec prune ({ agid = agid [@ trace]; clauses; adepth = depth ; agoal_hd = hd } as alts ) =
3476- if alts != cutto_alts then begin
3477- Format. fprintf fmt " %a" (pplist (ppclause ~depth ~hd ) " | " ) clauses;
3478- prune alts.next
3479- end in
3483+ let rec prune alts =
3484+ if alts = cutto_alts then () else
3485+ match alts with
3486+ | ExploreAnotherSLDPath ({ agid = agid [@ trace]; clauses; adepth = depth ; path = { predicate = hd } } as alts ) ->
3487+ Format. fprintf fmt " %a" (pplist (ppclause ~depth ~hd ) " | " ) clauses;
3488+ prune alts.alts
3489+ | Noalts -> ()
3490+ | UnblockSLGGenerator _ -> ()
3491+ in
34803492 prune alts
34813493 ) alts];
3482- if cutto_alts == noalts then T. trail := T. empty () ;
3494+ if cutto_alts == Noalts then T. trail := T. empty () ;
34833495 match gs with
34843496 | [] -> pop_andl cutto_alts next cutto_alts
34853497 | { depth; program; goal; gid = gid [@ trace] } :: gs -> run depth program goal (gid[@ trace]) gs next cutto_alts cutto_alts
@@ -3510,7 +3522,7 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
35103522 let sol = copy g in
35113523 [% spy " findall solution:" ~rid ~gid (ppterm depth [] ~argsdepth: 0 empty_env) g];
35123524 solutions := sol :: ! solutions in
3513- let alternatives = ref noalts in
3525+ let alternatives = ref Noalts in
35143526 try
35153527 alternatives := search () ;
35163528 add_sol () ;
@@ -3533,18 +3545,20 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
35333545
35343546 and pop_andl alts next cutto_alts =
35353547 match next with
3536- | FNil ->
3548+ | Done ->
35373549 (match resume_all () with
35383550 None ->
35393551 Fmt. fprintf Fmt. std_formatter
35403552 " Undo triggered by goal resumption\n %!" ;
35413553 [% tcall next_alt alts]
35423554 | Some ({ depth; program; goal; gid = gid [@ trace] } :: gs ) ->
3543- run depth program goal (gid[@ trace]) gs FNil alts cutto_alts
3555+ run depth program goal (gid[@ trace]) gs Done alts cutto_alts
35443556 | Some [] -> alts)
3545- | FCons ( _ , [] , _ ) -> anomaly " empty stack frame "
3546- | FCons ( cutto_alts , { depth; program; goal; gid = gid [@ trace] } :: gs , next ) ->
3557+ | SolveGoals { brothers = [] ; _ } -> anomaly " empty continuation "
3558+ | SolveGoals { cutto_alts; brothers = { depth; program; goal; gid = gid [@ trace] } :: gs ; next } ->
35473559 run depth program goal (gid[@ trace]) gs next alts cutto_alts
3560+ | ExitSLGRoot _ -> assert false
3561+ | TableSolution _ -> assert false
35483562
35493563 and resume_all () : goal list option =
35503564(* if fm then Some [] else *)
@@ -3584,13 +3598,14 @@ end;*)
35843598 else None
35853599
35863600 and next_alt alts =
3587- if alts == noalts then raise No_clause
3588- else
3589- let { program = p; clauses; agoal_hd = k; ogoal_arg = arg; ogoal_args = args; agid = gid [@ trace]; goals = gs; stack = next;
3590- trail = old_trail; state = old_state;
3591- adepth = depth; cutto_alts = cutto_alts; next = alts} = alts in
3592- T. undo ~old_trail ~old_state () ;
3593- backchain depth p (k, arg, args, gs) (gid[@ trace]) next alts cutto_alts clauses
3601+ match alts with
3602+ | ExploreAnotherSLDPath { program = p; clauses; path; agid = gid [@ trace]; stack = next;
3603+ trail = old_trail; state = old_state;
3604+ adepth = depth; cutto_alts = cutto_alts; alts} ->
3605+ T. undo ~old_trail ~old_state () ;
3606+ backchain depth p path (gid[@ trace]) next alts cutto_alts clauses
3607+ | UnblockSLGGenerator _ -> assert false
3608+ | Noalts -> raise No_clause
35943609 in
35953610
35963611 (* Finally the runtime *)
@@ -3622,7 +3637,7 @@ end;*)
36223637 let search = exec (fun () ->
36233638 [% spy " dev:trail:init" ~rid (fun fmt () -> T. print_trail fmt) () ];
36243639 set T. trail (T. empty () );
3625- run initial_depth ! orig_prolog_program initial_goal ((UUID. make () )[@ trace]) [] FNil noalts noalts ) in
3640+ run initial_depth ! orig_prolog_program initial_goal ((UUID. make () )[@ trace]) [] Done Noalts Noalts ) in
36263641 let destroy () = () in
36273642 let next_solution = exec next_alt in
36283643 incr max_runtime_id;
@@ -3651,8 +3666,8 @@ let mk_outcome search get_cs assignments =
36513666 } in
36523667 Success solution, alts
36533668 with
3654- | No_clause (*| Non_linear * ) -> Failure , noalts
3655- | No_more_steps -> NoMoreSteps , noalts
3669+ | No_clause (*| Non_linear * ) -> Failure , Noalts
3670+ | No_more_steps -> NoMoreSteps , Noalts
36563671
36573672let execute_once ?max_steps ?delay_outside_fragment exec =
36583673 auxsg := [] ;
@@ -3662,18 +3677,18 @@ let execute_once ?max_steps ?delay_outside_fragment exec =
36623677
36633678let execute_loop ?delay_outside_fragment exec ~more ~pp =
36643679 let { search; next_solution; get } = make_runtime ?delay_outside_fragment exec in
3665- let k = ref noalts in
3680+ let k = ref Noalts in
36663681 let do_with_infos f =
36673682 let time0 = Unix. gettimeofday() in
36683683 let o, alts = mk_outcome f (fun () -> get CS.Ugly. delayed, get CS. state |> State. end_execution, exec.query_arguments, { Data. uv_names = ref (get Pp. uv_names); table = get C. table }) exec.assignments in
36693684 let time1 = Unix. gettimeofday() in
36703685 k := alts;
36713686 pp (time1 -. time0) o in
36723687 do_with_infos search;
3673- while ! k != noalts do
3674- if not (more() ) then k := noalts else
3688+ while ! k != Noalts do
3689+ if not (more() ) then k := Noalts else
36753690 try do_with_infos (fun () -> next_solution ! k)
3676- with No_clause -> pp 0.0 Failure ; k := noalts
3691+ with No_clause -> pp 0.0 Failure ; k := Noalts
36773692 done
36783693;;
36793694
0 commit comments