我有以下定义:(将正整数定义为nat的子类型)
Definition Z_pos_filter (p: nat) : bool :=
if (beq_nat p 0) then false else true.
Definition Z_pos: Set := {n : nat | is_true (Z_pos_filter n) }.
Definition Z_pos__N (p: Z_pos): nat := proj1_sig p.
Definition Z_pos_mult (p q: Z_pos): Z_pos.
destruct (Z_pos_filter (Z_pos__N p * Z_pos__N q)) eqn:prf.
- exact ((exist _ (Z_pos__N p * Z_pos__N q) prf)).
- assert (forall n: nat, S n <> 0) by (intros; omega).
assert (forall a b: nat, a <> 0 /\ b <> 0 -> a * b <> 0).
{ intros. destruct a, b. omega. omega. omega. simpl. apply H. }
assert (forall r: Z_pos, Z_pos__N r <> 0) by apply Z_pos_nonzero_N.
assert (Z_pos__N p * Z_pos__N q <> 0) by (apply H0; split; apply H1).
unfold Z_pos_filter in prf.
rewrite <- beq_nat_false_iff in H2.
rewrite H2 in prf. inversion prf.
Defined.
但是我坚持要证明Z_pos_mult
与黑白乘法自然数兼容:
Lemma compat: forall p q: Z_pos, Z_pos__N (Z_pos_mult p q) = Z_pos__N p * Z_pos__N q.
我该如何解决?
答案 0 :(得分:1)
您对Z_pos_mult的定义太复杂了。它依赖于依赖模式匹配 从一开始就对。我建议仅将这种依赖模式匹配用于证明,而不用于定义。
这是一个替代定义。并不是在进行任何证明之前就固定了返回值。
Definition Z_pos_mult (p q : Z_pos) : Z_pos.
exists (Z_pos__N p * Z_pos__N q).
destruct p as [p ph]; destruct q as [q qh].
unfold Z_pos_filter in ph, qh |- *; simpl.
destruct (p =? 0) eqn: ph'; try discriminate.
destruct (q =? 0) eqn: qh'; try discriminate.
rewrite beq_nat_false_iff in ph'.
rewrite beq_nat_false_iff in qh'.
destruct (p * q =? 0) eqn:pqh'; auto.
rewrite beq_nat_true_iff in pqh'.
destruct p; destruct q; try solve[discriminate | case ph'; auto | case qh'; auto].
Defined.
有了这个定义,您要求的证明就很容易编写。
Lemma compat: forall p q: Z_pos, Z_pos__N (Z_pos_mult p q) = Z_pos__N p * Z_pos__N q.
Proof.
intros [p ph] [q qh]; unfold Z_pos_mult; simpl; auto.
Qed.
原则上,也可以为您的代码提供证明,但这非常困难。
答案 1 :(得分:1)
恕我直言,以原始形式回答这个问题是在提倡一种可疑的风格。我认为此类数字的乘积应仅是基本类型的乘积。并且证明应仅从投影的内射性得出,就像在mathcomp中所做的那样。
通常,如果归约后在术语中出现非完全不透明的证明,您将遇到很多问题。
答案 2 :(得分:0)
这就是我在香草Coq中的做法。我假设我们仍然可以调整定义。
WITH
-- Select Features
feat AS
(SELECT toid AS building_id,
wkb_geometry AS geom
FROM buildings
),
polygon_dump AS
(SELECT (ST_DumpAsPolygons(ST_Clip(a.st_roughness,1,b.geom,-9999,true))).val AS polygon_vals,building_id AS building_id2
FROM grosvenor_raster_roughness a, feat b
),
threshold AS
(SELECT building_id2 AS building_id, Count(*) AS thres_val
FROM polygon_dump
WHERE polygon_vals >= 0 AND polygon_vals < 0.5
GROUP BY building_id2
),
b_stats AS
(SELECT building_id, (stats).*
FROM (SELECT building_id, ST_SummaryStats(ST_Clip(a.st_roughness,1,b.geom,-9999,true)) AS stats
FROM grosvenor_raster_roughness a
INNER JOIN feat b
ON ST_Intersects(b.geom,a.st_roughness)
) AS foo
)
-- Summarise statistics
SELECT count As pixel_count,
thres_val AS threshold_val,
cast(thres_val as real)/cast(count as real)*100 AS percent_value,
min AS min_pixel_val,
max AS max_pixel_val,
mean AS avg_pixel_val,
stddev AS pixel_stddev
FROM b_stats
JOIN threshold USING(building_id)
WHERE count > 0;
让我补充一点,在SSReflect / Mathcomp中处理这种事情要愉快得多。