Zulip Chat Archive
Stream: general
Topic: decidable instance for `List.IsInfix`
Asei Inoue (Jan 10 2026 at 03:22):
I think decidable instance for List.IsInfix is missing.
I have proved this.
If you’re okay with it, I’d be happy to submit a PR.
import Lean
#check List.IsInfix
example : List.IsInfix [2, 3] [1, 2, 3, 4] := by
fail_if_success decide
exists [1], [4]
@[simp, grind]
def List.isInfix [DecidableEq α] (xs ys : List α) : Bool :=
match xs, ys with
| [], _ => true
| _ :: _, [] => false
| xs, ys@(_ :: ys') =>
if isPrefixOf xs ys then
true
else
isInfix xs ys'
#guard [2, 3].isInfix [1, 2, 3, 4]
#guard [1, 2].isInfix [1, 2, 3, 4]
#guard [3, 4].isInfix [1, 2, 3, 4]
#guard ! [2, 4].isInfix [1, 2, 3, 4]
theorem List.IsInfix_iff_isInfix [DecidableEq α] (xs ys : List α) :
xs.isInfix ys ↔ List.IsInfix xs ys := by
fun_induction List.isInfix with
| case1 => grind
| case2 => grind
| case3 => grind
| case4 =>
simp_all only [imp_false, List.isPrefixOf_iff_prefix]
grind [List.infix_cons_iff]
instance [DecidableEq α] (xs ys : List α) : Decidable (List.IsInfix xs ys) :=
decidable_of_iff _ (List.IsInfix_iff_isInfix xs ys)
example : List.IsInfix [2, 3] [1, 2, 3, 4] := by
decide
Yury G. Kudryashov (Jan 10 2026 at 03:47):
AFAIR, there is a better implementation in Batteries.
Yury G. Kudryashov (Jan 10 2026 at 03:53):
See https://github.com/leanprover-community/batteries/blob/main/Batteries/Data/Array/Match.lean, https://github.com/leanprover-community/batteries/blob/main/Batteries/Data/List/Matcher.lean, and https://github.com/leanprover-community/batteries/blob/main/Batteries/Data/String/Matcher.lean
Yury G. Kudryashov (Jan 10 2026 at 03:54):
It looks like their version has no proof of correctness.
Eric Wieser (Jan 10 2026 at 07:27):
docs#List.decidableInfix already exists
Last updated: Feb 28 2026 at 14:05 UTC