;; Extension — proximity (NEAR) search: terms within k positions, unordered.
;; Corpus:
;;   1 "the quick brown fox"    the0 quick1 brown2 fox3
;;   2 "quick the lazy fox dog" quick0 the1 lazy2 fox3 dog4
;;   3 "fox runs quick"         fox0 runs1 quick2

(define
  near-setup
  "idx = indexDoc 3 \"fox runs quick\" (indexDoc 2 \"quick the lazy fox dog\" (indexDoc 1 \"the quick brown fox\" emptyIndex))\n")

(define
  near-cases
  (list
    (list
      "near adjacent one doc"
      "nearDocs 1 \"quick\" \"brown\" idx"
      (list 1))
    (list
      "near adjacent both docs"
      "nearDocs 1 \"quick\" \"the\" idx"
      (list 1 2))
    (list
      "near within 2"
      "nearDocs 2 \"quick\" \"fox\" idx"
      (list 1 3))
    (list "near too far at k1" "nearDocs 1 \"quick\" \"fox\" idx" (list))
    (list
      "near unordered symmetric"
      "nearDocs 2 \"fox\" \"quick\" idx"
      (list 1 3))
    (list "near wider window" "nearDocs 5 \"the\" \"dog\" idx" (list 2))
    (list "near absent term" "nearDocs 1 \"quick\" \"zzz\" idx" (list))
    (list "near needs both terms" "nearDocs 3 \"brown\" \"dog\" idx" (list))
    (list
      "near same docs only"
      "nearDocs 3 \"fox\" \"runs\" idx"
      (list 3))))

(define
  near-results
  (search-batch near-setup (map (fn (c) (nth c 1)) near-cases)))

(map-indexed
  (fn
    (i c)
    (hk-test (nth c 0) (nth near-results i) (nth c 2)))
  near-cases)

{:fail hk-test-fail :pass hk-test-pass :fails hk-test-fails}
