我有一对不兼容的地图。我想知道什么是优雅/自动的方式来证明它。
AREA_X=1024; AREA_Y=576; OFFSET_X=110; OFFSET_Y=145
ffmpeg \
-async 1 -vsync 1 \
-loop 1 -i /home/helmi/Documents/Streaming.Chess.png \
-thread_queue_size 512 -f x11grab -s ${AREA_X}x${AREA_Y} -framerate 25 -async 1 -vsync 1 -i :0.0+${OFFSET_X},${OFFSET_Y} \
-thread_queue_size 512 -f v4l2 -framerate 25 -video_size 160x120 -i /dev/video0 \
-thread_queue_size 512 -f pulse -ac 2 -ar 48000 -i default \
-filter_complex \
"color=0x336699cc:1024x64, drawtext=textfile=/home/helmi/Documents/Streaming.Chess.txt:fontfile=/home/helmi/.fonts/PersonalUse_Clipper_Script_fat.ttf:x=10:y=16:fontsize=40:fontcolor=white [bottom]; \
[1:v]scale=960:-1,setpts=PTS-STARTPTS [a]; \
[0:v]setpts=PTS-STARTPTS [0v]; \
[0v][a]overlay=15:15 [b]; \
[b][2:v]overlay=(W-w):0 [c]; \
[c][bottom]overlay=0:H-64 [video]" \
-map "[video]" -map "3:a" \
-async 1 -vsync 1 \
-c:v libx264 -b:v 500k -maxrate 500k -bufsize 1000k -framerate 25 -crf 17 -preset superfast -pix_fmt yuv420p -tune zerolatency \
-force_key_frames "expr:gte(t,n_forced*2)" \
-c:a aac -b:a 256k -ac 2 -af "aresample=async=1" \
-f flv rtmp://live-vie.twitch.tv/app/...
答案 0 :(得分:2)
要使其自动化,您需要对证明策略进行准确的描述。这是一种可能的证明策略:
要证明total_map
的不等式:
t_update
,使用string_dec x x
为真并查看是否有其他string_dec
向下计算来简化所有这些等式假设。congruence
解决目标。我们可以自动执行每个步骤。总共变成:
Require Import Coq.Strings.String.
(* Prelude: the total_map data structure from Software Foundations, slightly modified *)
Definition total_map := string -> nat.
Definition empty_st : total_map := (fun _ => 0).
Definition t_update (m : total_map) k v := fun k' => if string_dec k k' then v else m k'.
Notation "a '!->' x" := (t_update empty_st a x) (at level 100).
Notation "x '!->' v ';' m" := (t_update m x v) (at level 100, v at next level, right associativity).
(* Automation *)
(* 1. First introduce the equality hypothesis. *)
Ltac start_proving_inequality H :=
intro H.
(* 2. Then, for every key that's been added to either map, add the hypothesis that the value associated to that key is the same in both maps. *)
(* To do this, we need a tactic that will pose a proof only if it does not already exist. *)
Ltac unique_pose_proof lem :=
let T := type of lem in
lazymatch goal with
| [ H : T |- _ ] => fail 0 "A hypothesis of type" T "already exists"
| _ => pose proof lem
end.
(* Maybe move this elsewhere? *)
Definition t_get (m : total_map) k := m k.
Ltac saturate_with_keys H :=
repeat match type of H with
| context[t_update _ ?k ?v]
=> unique_pose_proof (f_equal (fun m => t_get m k) H)
end.
(* 3. Then simplify all such equality hypotheses by unfolding `t_update`, using that `string_dec x x` is true, and seeing if any other `string_dec`s compute down. *)
Require Import Coq.Logic.Eqdep_dec.
Lemma string_dec_refl x : string_dec x x = left eq_refl.
Proof.
destruct (string_dec x x); [ apply f_equal | congruence ].
apply UIP_dec, string_dec.
Qed.
(* N.B. You can add more cases here to deal with other sorts of ways you might reduce [t_get] here *)
Ltac simplify_t_get_t_update_in H :=
repeat first [ progress cbv [t_get t_update empty_st] in H
| match type of H with
| context[string_dec ?x ?x] => rewrite (string_dec_refl x) in H
| context[string_dec ?x ?y]
=> let v := (eval cbv in (string_dec x y)) in
(* check that it fully reduces *)
lazymatch v with left _ => idtac | right _ => idtac end;
progress change (string_dec x y) with v in H
end ].
Ltac simplify_t_get_t_update :=
(* first we must change hypotheses of the form [(fun m => t_get m k) m = (fun m => t_get m k) m'] into [t_get _ _ = t_get _ _] *)
cbv beta in *;
repeat match goal with
| [ H : t_get _ _ = t_get _ _ |- _ ] => progress simplify_t_get_t_update_in H
end.
(* 4. Finally, solve the goal by `congruence`. *)
Ltac finish_proving_inequality := congruence.
(* Now we put it all together *)
Ltac prove_total_map_inequality :=
let H := fresh in
start_proving_inequality H;
saturate_with_keys H;
simplify_t_get_t_update;
finish_proving_inequality.
(* The actual goal I'm trying to solve *)
Definition X: string := "X".
Definition Y: string := "Y".
Goal forall n, (X !-> n; Y !-> n) <> (X !-> 1; Y !-> 2).
intros.
prove_total_map_inequality.
Qed.
答案 1 :(得分:0)
基于Jason Gross的回答以及total_map
是可判定类型的事实,我将一些自动化方法组合在一起来解决此问题。请注意,这个问题可能非常适合小规模反射。
(* TODO: don't bring trivial (n = n) or duplicated hypotheses into scope *)
(* Given two maps left and right, plus a lemma that they are equal, plus some key: assert that the values of the maps agree at the specified key *)
Ltac invert_total_map_equality_for_id lemma left right id :=
let H := fresh "H" in
assert (left id = right id) as H by (rewrite lemma; reflexivity);
cbv in H.
(* Recurse on the LHS map, extracting keys *)
Ltac invert_total_map_equality_left lemma left right left_remaining :=
match left_remaining with
| t_update ?left_remaining' ?id _ =>
invert_total_map_equality_for_id lemma left right id;
invert_total_map_equality_left lemma left right left_remaining'
| _ => idtac
end.
(* Recurse on the RHS map, extracting keys; move on to LHS once we've done all RHS keys *)
Ltac invert_total_map_equality_right lemma left right right_remaining :=
match right_remaining with
| t_update ?right_remaining' ?id _ =>
invert_total_map_equality_for_id lemma left right id;
invert_total_map_equality_right lemma left right right_remaining'
| _ => invert_total_map_equality_left lemma left right left
end.
(* Given a lemma that two total maps are equal, assert that their values agree at each defined key *)
Ltac invert_total_map_equality lem :=
let T := type of lem in
match T with
| ?left = ?right =>
match type of left with
| string -> nat =>
match type of right with
| string -> nat =>
invert_total_map_equality_right lem left right right
end
end
end.
Goal forall n, (X !-> n; Y !-> n) <> (X !-> 1; Y !-> 2).
Proof.
unfold not; intros.
invert_total_map_equality H.
congruence.
Qed.