@@ -23,7 +23,7 @@ Ltac2 rec term_to_string (t: constr): string :=
2323 Message.to_string msg.
2424
2525
26- Ltac2 rec apply_first (tacs: (unit -> constr ) list): constr :=
26+ Ltac2 rec apply_first (tacs: (unit -> 'a ) list): 'a :=
2727 match tacs with
2828 | [] => Control.zero (Tactic_failure (Some (fprintf "No tactic succeeded")))
2929 | tac :: rest =>
@@ -118,21 +118,29 @@ Ltac2 prove_contradiction self_loop: constr :=
118118 fprintf "Failed to derive a contradiction. Does your relation implement %t?" open_constr:(Irreflexive))))) in
119119 open_constr:(ltac2:(ltac1:(exfalso); exact $proof_false)).
120120
121+ Ltac2 Type walk_kind := [
122+ (* proof of path from `a` to `b` where edges and vertices are not repeated *)
123+ | Path (constr )
124+ (* proof of cycle from `a` to itself *)
125+ | Cycle (constr )
126+ ].
127+
121128(* in the graph `hyps_map` tries to find a path from `from` to `to` *)
122- Ltac2 find_path hyps_map from to: constr :=
129+ (* It might instead find a cycle for some `a` *)
130+ Ltac2 find_walk hyps_map from to: walk_kind :=
123131 let rec dfs visited goal current path :=
124132 match findi (String.equal current) visited with
125133 | Some idx =>
126134 (* we have found a cycle *)
127135 let cycle_proof := mk_trans (List.rev (List.firstn (Int.add idx 1) path)) in
128- prove_contradiction cycle_proof
136+ Cycle cycle_proof
129137 | None =>
130138 let visited := current :: visited in
131139 match FMap.find_opt current hyps_map with
132140 | Some lst =>
133141 let try_path (next, hyp_id) () :=
134142 if String.equal next goal then
135- mk_trans (List.rev (hyp_id :: path))
143+ Path ( mk_trans (List.rev (hyp_id :: path) ))
136144 else
137145 dfs visited goal next (hyp_id :: path) in
138146 apply_first (List.map try_path lst)
@@ -160,7 +168,10 @@ Ltac2 print_full_goal () :=
160168(* tries to find a cycle in the graph that will be a contradiction *)
161169Ltac2 find_contradiction hyps_map: constr :=
162170 let try_contra hyps_map name :=
163- prove_contradiction (find_path hyps_map name name) in
171+ prove_contradiction (match find_walk hyps_map name name with
172+ | Path pr => pr
173+ | Cycle pr => pr
174+ end ) in
164175 let rec try_contras hyps_map names :=
165176 match names with
166177 | name :: rest =>
@@ -176,7 +187,11 @@ Ltac2 solve_strict_order rel: unit :=
176187 let hyps_map := build_graph rel in
177188 let refined := match get_elements (Control.goal ()) rel with
178189 | Some (a_str, b_str) =>
179- Control.plus (fun _ => find_path hyps_map a_str b_str) (fun _ => find_contradiction hyps_map)
190+ Control.plus (fun _ =>
191+ match find_walk hyps_map a_str b_str with
192+ | Path pr => pr
193+ | Cycle pr => prove_contradiction pr
194+ end ) (fun _ => find_contradiction hyps_map)
180195 | _ =>
181196 find_contradiction hyps_map
182197 end in
0 commit comments