After reading the documentation for which-Nat, copied here:
(which-Nat target base step) → X
target : Nat
base : X
step : (-> Nat X)
which-Nat is a case operator on Nat.
Examples:
> (which-Nat 0 0 (λ (smaller) smaller))
(the Nat 0)
> (which-Nat 17 0 (λ (smaller) smaller))
(the Nat 16)
I tried to write my own clone of it, wN
, but the following claim
(claim wN
(Π ((E U )
(target Nat )
(base E )
(step (→ Nat E)))
(→ target base step
E)))
produces the error
; Expected U but given Nat
The fix is completely unsatisfying:
(claim wN
(Π ((E U )
(target Nat )
(base E )
(step (→ Nat E)))
(→ U U U ;target base step
E)))
All three U
are forced because if any one of target
, base
, and step
are used, I get the same failure.
This is all the more surprising, because my clone of the more challenging ind-Nat
, namely iN
, by a similar transcription of its documentation, works:
(claim iN
(Π ((t Nat) ; target
(m (→ Nat U)) ; motive
(b (m 0)) ; base
(s (Π ((n-1 Nat)) ; step
(→ (m n-1)
(m (add1 n-1))))))
(m t)))
(define iN
(λ (t m b s)
(ind-Nat
t
m
b
s)))
;; unit tests
(claim peas-ex
(Π ((ℓ Nat))
(Vec Atom ℓ)))
(define peas-ex
(λ (ℓ)
(iN ℓ
mot-peas
base-peas
step-peas)))
(peas-ex 0)
(peas-ex 1)
(peas-ex 2)
What is the most specific and correct type for which-Nat
that would let me define
a clone the way I did for ind-Nat
?