如何解决 FStar 中的这种类型冲突?
How to resolve this type conflict in FStar?
这是一个简单的模式生成器,returns 是 1:nat
的列表。 lemma_1
证明生成的任意长度列表的每个位置都有一个 1。必须引入 nth_1
的 lng
参数,否则 n
将被限制为 n:nat{n < length lst}
,导致与 lemma_1
中的 n
类型冲突其类型为 n:nat{n < lng}
。如果没有额外的参数,这怎么能解决?
val length: list 'a -> nat
let rec length lst =
match lst with
| [] -> 0
| _ :: t -> 1 + length t
val nth_1 : lst: list nat {length lst > 0} -> (lng: nat) -> n: nat {n < lng} -> nat
let rec nth_1 lst lng n =
match lst with
| [h] -> h
| h :: t -> if n = 0 then h else nth_1 t (lng - 1) (n - 1)
val gen_1 : lng: nat {lng > 0} -> list nat
let rec gen_1 lng =
match lng with
| 1 -> [1]
| _ -> 1 :: gen_1 (lng - 1)
let rec lemma_1 (lng: nat {lng > 0}) (n: nat {n < lng}) : Lemma ((nth_1 (gen_1 lng) lng n) = 1) =
match n with
| 0 -> ()
| _ -> lemma_1 (lng - 1) (n - 1)
问题似乎与 gen_1
模式长度不能为零的约束有关。有没有更好的表达方式?
这是避免额外参数的一种方法(请参阅内联评论):
module Test
val length: list α → ℕ
let rec length lst =
match lst with
| [] → 0
| _ ⸬ t → 1 + length t
//the refinement on n is not really necessary here, the proofs work even without it
//because as soon as we have [h], irrespective of the value of n, we return h
val nth_1 : lst: list ℕ {length lst > 0} → n: ℕ{n < length lst} → ℕ
let rec nth_1 lst n =
match lst with
| [h] → h
| h ⸬ t → if n = 0 then h else nth_1 t (n - 1)
//refine the return type to say that it returns a list of length lng
val gen_1 : lng: pos → (l:list ℕ{length l == lng})
let rec gen_1 lng =
match lng with
| 1 → [1]
| _ → 1 ⸬ gen_1 (lng - 1)
let rec lemma_1 (lng: pos) (n: ℕ {n < lng}) : Lemma ((nth_1 (gen_1 lng) n) = 1) =
match n with
| 0 → ()
| _ → lemma_1 (lng - 1) (n - 1)
这是一个简单的模式生成器,returns 是 1:nat
的列表。 lemma_1
证明生成的任意长度列表的每个位置都有一个 1。必须引入 nth_1
的 lng
参数,否则 n
将被限制为 n:nat{n < length lst}
,导致与 lemma_1
中的 n
类型冲突其类型为 n:nat{n < lng}
。如果没有额外的参数,这怎么能解决?
val length: list 'a -> nat
let rec length lst =
match lst with
| [] -> 0
| _ :: t -> 1 + length t
val nth_1 : lst: list nat {length lst > 0} -> (lng: nat) -> n: nat {n < lng} -> nat
let rec nth_1 lst lng n =
match lst with
| [h] -> h
| h :: t -> if n = 0 then h else nth_1 t (lng - 1) (n - 1)
val gen_1 : lng: nat {lng > 0} -> list nat
let rec gen_1 lng =
match lng with
| 1 -> [1]
| _ -> 1 :: gen_1 (lng - 1)
let rec lemma_1 (lng: nat {lng > 0}) (n: nat {n < lng}) : Lemma ((nth_1 (gen_1 lng) lng n) = 1) =
match n with
| 0 -> ()
| _ -> lemma_1 (lng - 1) (n - 1)
问题似乎与 gen_1
模式长度不能为零的约束有关。有没有更好的表达方式?
这是避免额外参数的一种方法(请参阅内联评论):
module Test
val length: list α → ℕ
let rec length lst =
match lst with
| [] → 0
| _ ⸬ t → 1 + length t
//the refinement on n is not really necessary here, the proofs work even without it
//because as soon as we have [h], irrespective of the value of n, we return h
val nth_1 : lst: list ℕ {length lst > 0} → n: ℕ{n < length lst} → ℕ
let rec nth_1 lst n =
match lst with
| [h] → h
| h ⸬ t → if n = 0 then h else nth_1 t (n - 1)
//refine the return type to say that it returns a list of length lng
val gen_1 : lng: pos → (l:list ℕ{length l == lng})
let rec gen_1 lng =
match lng with
| 1 → [1]
| _ → 1 ⸬ gen_1 (lng - 1)
let rec lemma_1 (lng: pos) (n: ℕ {n < lng}) : Lemma ((nth_1 (gen_1 lng) n) = 1) =
match n with
| 0 → ()
| _ → lemma_1 (lng - 1) (n - 1)