@@ -3014,29 +3014,37 @@ let repack_goal (gid[@trace]) ~depth program goal =
30143014 { depth ; program ; goal ; gid = gid [@ trace] }
30153015 [@@ inline]
30163016
3017-
3018- (* The activation frames points to the choice point that
3019- cut should backtrack to, i.e. the first one not to be
3020- removed. We call it catto_alts in the code. *)
3021- type frame =
3022- | FNil
3023- | FCons of (* lvl:*) alternative * goal list * frame
3024- and alternative = {
3025- cutto_alts : alternative ;
3026- program : prolog_prog ;
3027- adepth : int ;
3028- agoal_hd : constant ;
3029- ogoal_arg : term ;
3030- ogoal_args : term list ;
3031- agid : UUID .t ; [@ trace]
3032- goals : goal list ;
3033- stack : frame ;
3034- trail : T .trail ;
3035- state : State .t ;
3036- clauses : clause list ;
3037- next : alternative ;
3017+ type goals_crumbles = {
3018+ predicate : constant ;
3019+ fst_arg : term ;
3020+ other_args : term list ;
3021+ brothers : goal list ;
30383022}
3039- let noalts : alternative = Obj. magic (Sys. opaque_identity 0 )
3023+
3024+ (* The tree *)
3025+ type continuation = (* the AND part, what to do next *)
3026+ | Done
3027+ | ExitSLGRoot of { heap : unit ; next : continuation ; alts : alternative }
3028+ | TableSolution of unit
3029+ | SolveGoals of { cutto_alts : alternative ; brothers : goal list ; next : continuation }
3030+ and alternative = (* the OR part, what to do if we fail *)
3031+ | Noalts
3032+ | UnblockSLGGenerator of slg_generator (* a branch of the tree that could have been cut *)
3033+ | ExploreAnotherSLDPath of {
3034+ program : prolog_prog ;
3035+ adepth : int ;
3036+ path : goals_crumbles ;
3037+ agid : UUID .t ; [@ trace]
3038+ stack : continuation ;
3039+ trail : T .trail ;
3040+ state : State .t ;
3041+ clauses : clause list ;
3042+ alts : alternative ;
3043+ cutto_alts : alternative ;
3044+ }
3045+ and slg_generator =
3046+ | Root of { root_goal : term ; root_goal_args : int ; clauses : clause list ; }
3047+ | UnexploredBranches of { heap : unit ; alts : alternative }
30403048
30413049(* *****************************************************************************
30423050 Constraint propagation
@@ -3719,7 +3727,7 @@ let pp_CHR_resumed_goal { depth; program; goal; gid = gid[@trace] } =
37193727let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x executable -> 'x runtime =
37203728 (* Input to be read as the orl (((p,g)::gs)::next)::alts
37213729 depth >= 0 is the number of variables in the context. *)
3722- let rec run depth p g (gid [@trace ]) gs (next : frame ) alts cutto_alts =
3730+ let rec run depth p g (gid [@trace ]) gs (next : continuation ) alts cutto_alts =
37233731 [% cur_pred (pred_of g)];
37243732 [% trace " run" ~rid begin
37253733
@@ -3804,17 +3812,17 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
38043812 let clauses = get_clauses ~depth k g p in
38053813 [% spy " user:rule" ~rid ~gid pp_string " backchain" ];
38063814 [% spyl " user:rule:backchain:candidates" ~rid ~gid (pp_candidate ~depth ~k ) clauses];
3807- [% tcall backchain depth p (k, C. dummy, [] , gs) (gid[@ trace]) next alts cutto_alts clauses]
3815+ [% tcall backchain depth p { predicate = k; fst_arg = C. dummy; other_args = [] ; brothers = gs} (gid[@ trace]) next alts cutto_alts clauses]
38083816 | App (k ,x ,xs ) ->
38093817 let clauses = get_clauses ~depth k g p in
38103818 [% spy " user:rule" ~rid ~gid pp_string " backchain" ];
38113819 [% spyl " user:rule:backchain:candidates" ~rid ~gid (pp_candidate ~depth ~k ) clauses];
3812- [% tcall backchain depth p (k, x, xs, gs) (gid[@ trace]) next alts cutto_alts clauses]
3820+ [% tcall backchain depth p { predicate = k; fst_arg = x; other_args = xs; brothers = gs} (gid[@ trace]) next alts cutto_alts clauses]
38133821 | Builtin (c , args ) -> [% spy " user:rule" ~rid ~gid pp_string " builtin" ]; [% spy " user:rule:builtin:name" ~rid ~gid pp_string (C. show c)];
38143822 let once ~depth g state =
38153823 CS. state := state;
38163824 let { depth; program; goal; gid = gid [@ trace] } = (make_subgoal[@ inlined]) (gid[@ trace]) ~depth p g in
3817- let _alts = run depth program goal (gid[@ trace]) [] FNil noalts noalts in
3825+ let _alts = run depth program goal (gid[@ trace]) [] Done Noalts Noalts in
38183826 ! CS. state in
38193827 begin match Constraints. exect_builtin_predicate ~once c ~depth p (gid[@ trace]) args with
38203828 | gs' ->
@@ -3833,15 +3841,15 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
38333841 error " The goal is a flexible term"
38343842 end ]
38353843
3836- (* We pack some arguments into a tuple otherwise we consume too much stack *)
3837- and backchain depth p (k , arg , args_of_g , gs ) (gid [@trace ]) next alts cutto_alts cp = [% trace " select" ~rid begin
3844+ (* We pack some arguments into the goals_crumbles record otherwise we consume too much stack *)
3845+ 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
38383846 match cp with
38393847 | [] -> [% spy " user:rule:backchain" ~rid ~gid pp_string " fail" ];
38403848 [% tcall next_alt alts]
38413849 | { depth = c_depth ; mode = c_mode ; args = c_args ; hyps = c_hyps ; vars = c_vars ; loc } :: cs ->
38423850 [% spy " user:rule:backchain:try" ~rid ~gid (pp_option Util.CData. pp) (Util. option_map Ast. cloc.Util.CData. cin loc) (ppclause ~hd: k) { depth = c_depth; mode = c_mode; args = c_args; hyps = c_hyps; vars = c_vars; loc }];
38433851 let old_trail = ! T. trail in
3844- T. last_call := alts == noalts && cs == [] ;
3852+ T. last_call := alts == Noalts && cs == [] ;
38453853 let env = Array. make c_vars C. dummy in
38463854 match
38473855 match c_args with
@@ -3851,23 +3859,22 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
38513859 | [] -> 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
38523860 | arg_mode :: ms -> unif ~argsdepth: depth ~matching: (arg_mode == Input ) (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
38533861 with
3854- | false ->
3855- T. undo ~old_trail () ; [% tcall backchain depth p (k, arg, args_of_g, gs) (gid[@ trace]) next alts cutto_alts cs]
3862+ | false -> T. undo old_trail () ; [% tcall backchain depth p g_gs (gid[@ trace]) next alts cutto_alts cs]
38563863 | true ->
38573864 let oldalts = alts in
38583865 let alts = if cs = [] then alts else
3859- { program = p; adepth = depth; agoal_hd = k; ogoal_arg = arg; ogoal_args = args_of_g; agid = gid[@ trace]; goals = gs ; stack = next;
3866+ ExploreAnotherSLDPath { program = p; adepth = depth; path = g_gs; agid = gid[@ trace]; stack = next;
38603867 trail = old_trail;
38613868 state = ! CS. state;
3862- clauses = cs; cutto_alts = cutto_alts ; next = alts} in
3869+ clauses = cs; cutto_alts = cutto_alts ; alts} in
38633870 begin match c_hyps with
38643871 | [] ->
38653872 [% spy " user:rule:backchain" ~rid ~gid pp_string " success" ];
38663873 begin match gs with
38673874 | [] -> [% tcall pop_andl alts next cutto_alts]
38683875 | { depth ; program; goal; gid = gid [@ trace] } :: gs -> [% tcall run depth program goal (gid[@ trace]) gs next alts cutto_alts] end
38693876 | h ::hs ->
3870- let next = if gs = [] then next else FCons ( cutto_alts,gs, next) in
3877+ let next = if gs = [] then next else SolveGoals { cutto_alts; brothers = gs; next } in
38713878 let h = move ~argsdepth: depth ~from: c_depth ~to_: depth env h in
38723879 let gid[@ trace] = make_subgoal_id gid ((depth,h)[@ trace]) in
38733880 let hs =
@@ -3881,15 +3888,19 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
38813888 and cut (gid [@trace ]) gs next (alts [@trace ]) cutto_alts =
38823889 [% spy " user:rule" ~rid ~gid pp_string " cut" ];
38833890 let () [@ trace] =
3884- let rec prune ({ agid = agid [@ trace]; clauses; adepth = depth ; agoal_hd = hd } as alts ) =
3885- if alts != cutto_alts then begin
3886- List. iter (fun c ->
3887- [% spy " user:rule:cut:branch" ~rid UUID. pp agid (pp_option Util.CData. pp) (Util. option_map Ast. cloc.Util.CData. cin c.loc) (ppclause ~hd ) c])
3888- clauses;
3889- prune alts.next
3890- end in
3891+ let rec prune alts =
3892+ if alts == cutto_alts then () else
3893+ match alts with
3894+ | ExploreAnotherSLDPath ({ agid = agid [@ trace]; clauses; adepth = depth ; path = { predicate = hd } } as alts ) ->
3895+ List. iter (fun c ->
3896+ [% spy " user:rule:cut:branch" ~rid UUID. pp agid (pp_option Util.CData. pp) (Util. option_map Ast. cloc.Util.CData. cin c.loc) (ppclause ~hd ) c])
3897+ clauses;
3898+ prune alts.alts
3899+ | Noalts -> ()
3900+ | UnblockSLGGenerator _ -> ()
3901+ in
38913902 prune alts in
3892- if cutto_alts == noalts then T. trail := T. empty () ;
3903+ if cutto_alts == Noalts then T. trail := T. empty () ;
38933904 match gs with
38943905 | [] -> pop_andl cutto_alts next cutto_alts
38953906 | { depth; program; goal; gid = gid [@ trace] } :: gs -> run depth program goal (gid[@ trace]) gs next cutto_alts cutto_alts
@@ -3921,7 +3932,7 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
39213932 let sol = copy g in
39223933 [% spy " findall solution:" ~rid ~gid (ppterm depth [] ~argsdepth: 0 empty_env) g];
39233934 solutions := sol :: ! solutions in
3924- let alternatives = ref noalts in
3935+ let alternatives = ref Noalts in
39253936 try
39263937 alternatives := search () ;
39273938 add_sol () ;
@@ -3947,18 +3958,20 @@ let make_runtime : ?max_steps: int -> ?delay_outside_fragment: bool -> 'x execut
39473958
39483959 and pop_andl alts next cutto_alts =
39493960 match next with
3950- | FNil ->
3961+ | Done ->
39513962 (match resume_all () with
39523963 None ->
39533964 Fmt. fprintf Fmt. std_formatter
39543965 " Undo triggered by goal resumption\n %!" ;
39553966 [% tcall next_alt alts]
39563967 | Some ({ depth; program; goal; gid = gid [@ trace] } :: gs ) ->
3957- run depth program goal (gid[@ trace]) gs FNil alts cutto_alts
3968+ run depth program goal (gid[@ trace]) gs Done alts cutto_alts
39583969 | Some [] -> alts)
3959- | FCons ( _ , [] , _ ) -> anomaly " empty stack frame "
3960- | FCons ( cutto_alts , { depth; program; goal; gid = gid [@ trace] } :: gs , next ) ->
3970+ | SolveGoals { brothers = [] ; _ } -> anomaly " empty continuation "
3971+ | SolveGoals { cutto_alts; brothers = { depth; program; goal; gid = gid [@ trace] } :: gs ; next } ->
39613972 run depth program goal (gid[@ trace]) gs next alts cutto_alts
3973+ | ExitSLGRoot _ -> assert false
3974+ | TableSolution _ -> assert false
39623975
39633976 and resume_all () : goal list option =
39643977(* if fm then Some [] else *)
@@ -4028,20 +4041,20 @@ end;*)
40284041 end
40294042
40304043 and next_alt alts =
4031- if alts == noalts then raise No_clause
4032- else
4033- let { program = p; clauses; agoal_hd = k; ogoal_arg = arg; ogoal_args = args; agid = gid [ @ trace]; goals = gs; stack = next ;
4034- trail = old_trail; state = old_state;
4035- adepth = depth; cutto_alts = cutto_alts; next = alts} = alts in
4036- T. undo ~old_trail ~old_state () ;
4037-
4038- [ % trace " run " ~rid begin
4039- [ % cur_pred ( Some ( C. show k)) ];
4040- [% spyl " user:curgoal " ~rid ~gid (uppterm depth [] ~argsdepth: 0 empty_env) [ Const k; App (k,arg,args)] ];
4041- [ % spy " user:rule " ~rid ~ gid pp_string " backchain " ];
4042- [ % spyl " user:rule:backchain:candidates " ~rid ~gid (pp_candidate ~depth ~k ) clauses];
4043- [ % tcall backchain depth p (k, arg, args, gs) (gid[ @ trace]) next alts cutto_alts clauses]
4044- end ]
4044+ match alts with
4045+ | ExploreAnotherSLDPath { program = p; clauses; path; agid = gid [ @ trace]; stack = next;
4046+ trail = old_trail; state = old_state ;
4047+ adepth = depth; cutto_alts = cutto_alts; alts} ->
4048+ T. undo ~old_trail ~old_state () ;
4049+ [ % trace " run " ~rid begin
4050+ [ % cur_pred ( Some ( C. show path.predicate))];
4051+ [ % spyl " user:curgoal " ~rid ~gid (uppterm depth [] ~argsdepth: 0 empty_env) [ Const path.predicate; App (path.predicate,path.fst_arg,path.other_args)]];
4052+ [ % spy " user:rule " ~rid ~gid pp_string " backchain " ];
4053+ [% spyl " user:rule:backchain:candidates " ~rid ~gid (pp_candidate ~ depth ~k: (path.predicate)) clauses ];
4054+ [ % tcall backchain depth p path ( gid[ @ trace]) next alts cutto_alts clauses]
4055+ end ]
4056+ | UnblockSLGGenerator _ -> assert false
4057+ | Noalts -> raise No_clause
40454058 in
40464059
40474060 (* Finally the runtime *)
@@ -4077,7 +4090,7 @@ end;*)
40774090 let gid[@ trace] = UUID. make () in
40784091 [% spy " user:newgoal" ~rid ~gid (uppterm initial_depth [] ~argsdepth: 0 empty_env) initial_goal];
40794092 set T. trail (T. empty () );
4080- run initial_depth ! orig_prolog_program initial_goal (gid[@ trace]) [] FNil noalts noalts ) in
4093+ run initial_depth ! orig_prolog_program initial_goal (gid[@ trace]) [] Done Noalts Noalts ) in
40814094 let destroy () = () in
40824095 let next_solution = exec next_alt in
40834096 incr max_runtime_id;
@@ -4107,8 +4120,8 @@ let mk_outcome search get_cs assignments depth =
41074120 } in
41084121 Success solution, alts
41094122 with
4110- | No_clause (*| Non_linear * ) -> Failure , noalts
4111- | No_more_steps -> NoMoreSteps , noalts
4123+ | No_clause (*| Non_linear * ) -> Failure , Noalts
4124+ | No_more_steps -> NoMoreSteps , Noalts
41124125
41134126let execute_once ?max_steps ?delay_outside_fragment exec =
41144127 let { search; get } = make_runtime ?max_steps ?delay_outside_fragment exec in
@@ -4124,20 +4137,20 @@ let execute_once ?max_steps ?delay_outside_fragment exec =
41244137
41254138let execute_loop ?delay_outside_fragment exec ~more ~pp =
41264139 let { search; next_solution; get; destroy } = make_runtime ?delay_outside_fragment exec in
4127- let k = ref noalts in
4140+ let k = ref Noalts in
41284141 let do_with_infos f =
41294142 let time0 = Unix. gettimeofday() in
41304143 let o, alts = mk_outcome f (fun () -> get CS.Ugly. delayed, (exec.initial_depth,get CS. state), get CS. state |> State. end_execution, exec.query_arguments, { Data. uv_names = ref (get Pp. uv_names); table = get C. table }) exec.assignments exec.initial_depth in
41314144 let time1 = Unix. gettimeofday() in
41324145 k := alts;
41334146 pp (time1 -. time0) o in
41344147 do_with_infos search;
4135- while ! k != noalts do
4136- if not (more() ) then k := noalts else
4148+ while ! k != Noalts do
4149+ if not (more() ) then k := Noalts else
41374150 try do_with_infos (fun () -> next_solution ! k)
41384151 with
4139- | No_clause -> pp 0.0 Failure ; k := noalts ; [% end_trace " execute_loop" ~rid ]
4140- | e -> pp 0.0 Failure ; k := noalts ; [% end_trace " execute_loop" ~rid ]; raise e
4152+ | No_clause -> pp 0.0 Failure ; k := Noalts ; [% end_trace " execute_loop" ~rid ]
4153+ | e -> pp 0.0 Failure ; k := Noalts ; [% end_trace " execute_loop" ~rid ]; raise e
41414154 done
41424155;;
41434156
0 commit comments