coq tactic - Simplifying Subformulas in Coq -


i'm trying solve equation of form

a * b * c * d * e = f 

where * complicated left associative operation.

at moment, opaque (including * , a through f), , can made transparent via autounfold m_db.

the problem if globally unfold definition in formula, simplification take forever. instead, want first unfold a * b, apply tactics reduce normal form x, , same x * c , forth.

any idea how accomplish this? here's current approach in a or at a doesn't work. also, it's not clear me whether right structure, or reduce_m ought return something.

ltac reduce_m m :=   match m   | ?a × ?b => reduce_m a;               reduce_m b;               simpl;               autorewrite c_db   | ?a      => autounfold m_db (* in *);               simpl;                autorewrite c_db   end.   ltac simpl_m :=    match goal   | [|- ?m = _ ] => reduce_m m   end. 

a minimalish example:

require import arith.  definition add_f (f g : nat -> nat) :=  fun x => f x + g x.  infix "+" := add_f.  definition f := fun x => if x =? 4 1 else 0. definition g := fun x => if x <=? 4 3 else 0. definition h := fun x => if x =? 2 2 else 0.  lemma ex : f + g + h = fun x => match x                              | 0 => 3                              | 1 => 3                              | 2 => 5                              | 3 => 3                              | 4 => 4                              | _ => 0                               end. 

you can put term in hypothesis , autounfold in that. is, can replace

autounfold m_db (* in *) 

with

let aterm := fresh in set (aterm := a); autounfold m_db in aterm; subst aterm 

if a big, slow, because set complicated , sort of reduction. if case, can set goal have:

ha     : a' = hb     : b' = b hc     : c' = c hd     : d' = d     : e' = e hab    : ab = a' * b' habc   : abc = ab * c' habcd  : abcd = abc * d' habcde : abcde = abcd * e' ------------------------ abcde = f 

and can like

ltac reduce h :=   autounfold m_db in h; simpl in h; autorewrite c_db in h.  reduce ha; reduce hb; reduce hc; reduce hd; reduce he; subst a' b'; reduce hab; subst ab c'; reduce habc; subst abc d'; reduce habcd; subst abcd e'; reduce habcde; subst abcde. 

update account example:

to reduction on function, indeed need either function extensionality, or use relation other =. however, don't need function extensionality modularization bits:

require import arith.  definition add_f (f g : nat -> nat) :=  fun x => f x + g x.  infix "+" := add_f.  definition f := fun x => if x =? 4 1 else 0. definition g := fun x => if x <=? 4 3 else 0. definition h := fun x => if x =? 2 2 else 0.  ltac save x x' h :=   remember x x' eqn:h in *.  lemma ex : f + g + h = fun x => match x                                 | 0 => 3                                 | 1 => 3                                 | 2 => 5                                 | 3 => 3                                 | 4 => 4                                 | _ => 0                                  end. proof.   save f f' hf; save g g' hg; save h h' hh;   save (f' + g') fg hfg; save (fg + h') fgh hfgh.   cbv [f g] in *.   subst f' g'.   cbv [add_f] in hfg.   (* note: if want simplify [(if x =? 4 1 else 0) +       (if x <=? 4 3 else 0)], need function       extensionality.  however, don't need       modularize simplification. *) 

alternatively, if set goal bit differently, can avoid function extensionality:

require import arith coq.classes.relationclasses coq.setoids.setoid coq.classes.morphisms.  definition add_f (f g : nat -> nat) :=  fun x => f x + g x.  infix "+" := add_f.  definition f := fun x => if x =? 4 1 else 0. definition g := fun x => if x <=? 4 3 else 0. definition h := fun x => if x =? 2 2 else 0.  ltac save x x' h :=   remember x x' eqn:h in *. definition nat_case (p : nat -> type) (o : p 0) (s : forall n, p (s n)) (x : nat) : p x   := match x      | 0 => o      | s n' => s n'      end. lemma nat_case_plus (a a' : nat) (b b' : nat -> nat) (x : nat)   : (nat_case _ b x + nat_case _ a' b' x)%nat = nat_case _ (a + a')%nat (fun x => b x + b' x)%nat x. proof. destruct x; reflexivity. qed. lemma nat_case_plus_const (a : nat) (b : nat -> nat) (x : nat) (y : nat)   : (nat_case _ b x + y)%nat = nat_case _ (a + y)%nat (fun x => b x + y)%nat x. proof. destruct x; reflexivity. qed. global instance nat_case_proper {p} : proper (eq ==> forall_relation (fun _ => eq) ==> forall_relation (fun _ => eq)) (nat_case p). proof.   unfold forall_relation; intros x x' ? f f' hf [|a]; unfold nat_case; auto. qed. global instance nat_case_proper' {p} : proper (eq ==> pointwise_relation _ eq ==> forall_relation (fun _ => eq)) (nat_case (fun _ => p)). proof.   unfold forall_relation, pointwise_relation; intros x x' ? f f' hf [|a]; unfold nat_case; auto. qed. global instance nat_case_proper'' {p} {x} : proper (pointwise_relation _ eq ==> eq ==> eq) (nat_case (fun _ => p) x). proof.   intros ??? b ?; subst b; destruct a; simpl; auto. qed. global instance nat_case_proper''' {p} {x} : proper (forall_relation (fun _ => eq) ==> eq ==> eq) (nat_case (fun _ => p) x). proof.   intros ??? b ?; subst b; destruct a; simpl; auto. qed. ltac reduce :=   let solve_tac := unfold nat_case; repeat match goal |- context[match ?x o => _ | _ => _ end] => destruct x end; reflexivity in   repeat match goal          | [ h : context[if ?x =? 4 ?a else ?b] |- _ ]            => replace (if x =? 4 else b) (match x 4 => | _ => b end) in h solve_tac          | [ h : context[if ?x =? 2 ?a else ?b] |- _ ]            => replace (if x =? 2 else b) (match x 2 => | _ => b end) in h solve_tac          | [ h : context[if ?x <=? 4 ?a else ?b] |- _ ]            => replace (if x <=? 4 else b) (match x 0 | 1 | 2 | 3 | 4 => | _ => b end) in h solve_tac          | [ h : context g[match ?x x' in nat return @?t x' o => ?a | s n => @?s n end] |- _ ]            => let g' := context g[@nat_case t s x] in               change g' in h          | [ h : context g[fun v => match @?x v x' in nat return @?t x' o => ?a | s n => @?s n end] |- _ ]            => let g' := context g[fun v => @nat_case t s (x v)] in               change g' in h; cbv beta in *          | [ h : context[(nat_case _ _ _ _ + nat_case _ _ _ _)%nat] |- _ ]            => progress repeat setoid_rewrite nat_case_plus in h; simpl in h          | [ h : context[(nat_case _ _ _ _ + _)%nat] |- _ ]            => progress repeat setoid_rewrite nat_case_plus_const in h; simpl in h          end. lemma ex : forall x, (f + g + h) x = match x                                      | 0 => 3                                      | 1 => 3                                      | 2 => 5                                      | 3 => 3                                      | 4 => 4                                      | _ => 0                                       end. proof.   intro x; cbv [add_f].   save (f x) f' hf; save (g x) g' hg; save (h x) h' hh; save (f' + g')%nat fg hfg; save (fg + h')%nat fgh hfgh.   cbv [f g] in *.   subst f' g'; reduce.   cbv [h] in *; reduce.   subst fg h'; reduce.   subst fgh.   unfold nat_case.   reflexivity. qed. 

Comments

Popular posts from this blog

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -

python - Error while using APScheduler: 'NoneType' object has no attribute 'now' -