Skip to content

Commit 6f8de4a

Browse files
committed
Fix finding cycles when looking for paths
1 parent 9a07e8c commit 6f8de4a

2 files changed

Lines changed: 30 additions & 6 deletions

File tree

Solver.v

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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 *)
161169
Ltac2 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

Tests.v

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,15 @@ Section Tests.
200200
strict_order lt.
201201
Qed.
202202

203+
(* finding cycles while looking for paths *)
204+
Goal forall a b,
205+
(* here, we look for a cycle for `a` but while doing so we find the cycle `b`<->`b` *)
206+
lt a b -> lt b b -> False.
207+
Proof.
208+
intros.
209+
strict_order lt.
210+
Qed.
211+
203212
(* ---- Long chains ---- *)
204213

205214
(* 10-element chain *)

0 commit comments

Comments
 (0)