How to make algebraic manipulations in Coq easier?How to end this Proof in CoqProving a theorem in Coq using almost only rewrites - no “cleverness”Defining interval function in CoqProof by case analysis in CoqCannot rewrite subterm in CoqNot equal succesors in CoqProof automation in Coq how to factorize a proofCoq modular arithmeticProving a contradiction in CoqProving (~A -> ~B)-> (~A -> B) -> A in Coq

Could Boris Johnson face criminal charges for illegally proroguing Parliament?

What is the difference between increasing volume and increasing gain?

How to say "respectively" in German when listing (enumerating) things

Does publication of the phone call ruin the basis for impeachment?

Using RECURSIVE in Virtual Layer

Is "weekend warrior" derogatory?

Bothered by watching coworkers slacking off

Did Joe Biden "stop a prosecution" into his son in Ukraine? And did he brag about stopping the prosecution?

Is there a way to replace Smite with Sharpness on a weapon?

When Vesuvan Shapeshifter copies turn face up replacement effects, why do they work?

What's the correct way to determine turn order in this situation?

Re-entering the UK after overstaying in 2008

What does a textbook look like while you are writing it?

How do we know Nemesis is not a black hole (or neutron star)?

Writing about real people - not giving offence

Should I be an author on another PhD student's paper if I went to their meetings and gave advice?

Quote to show students don't have to fear making mistakes

Booting Ubuntu from USB drive on MSI motherboard -- EVERYTHING fails

Airport Security - advanced check, 4th amendment breach

Is there an in-universe explanation of how Frodo's arrival in Valinor was recorded in the Red Book?

Where does the image of a data connector as a sharp metal spike originate from?

Why not add cuspidal curves in the moduli space of stable curves?

Everyone Gets a Window Seat

How to "Start as close to the end as possible", and why to do so?



How to make algebraic manipulations in Coq easier?


How to end this Proof in CoqProving a theorem in Coq using almost only rewrites - no “cleverness”Defining interval function in CoqProof by case analysis in CoqCannot rewrite subterm in CoqNot equal succesors in CoqProof automation in Coq how to factorize a proofCoq modular arithmeticProving a contradiction in CoqProving (~A -> ~B)-> (~A -> B) -> A in Coq






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty
margin-bottom:0;









1















I'm experimenting with Coq's standard libraries for integers and rationals. So far my proofs are very time-consuming and look terrible.
I guess I miss some important proof techniques. Such simple lemmas shouldn't be so long to prove. Any hints?



Here is an example:



Require Import ZArith.
Require Import QArith.
Open Scope Q_scope.

Theorem q_less: forall x y z, (0 <= x <= y)%Z -> x # z <= y # z.
Proof. intros. destruct H as [Hl Hr]. rewrite (Zle_Qle x y) in Hr.
rewrite <- (Qmult_le_l (inject_Z x) (inject_Z y) (/ inject_Z (Zpos z))) in Hr. simpl in Hr.
- rewrite Qmult_comm in Hr. rewrite Qmult_comm with (x := / inject_Z (Z.pos z)) in Hr.
unfold inject_Z in Hr. unfold Qinv in Hr. destruct (Qnum (Z.pos z # 1)) eqn:ZV.
+ simpl in ZV. discriminate.
+ simpl in Hr. simpl in ZV. injection ZV. intro ZP. unfold Qmult in Hr. simpl in Hr.
rewrite <- ZP in Hr. rewrite Z.mul_1_r in Hr. rewrite Z.mul_1_r in Hr. exact Hr.
+ simpl in ZV. discriminate.
- unfold Qinv. simpl. apply Z.lt_0_1.
Qed.









share|improve this question






























    1















    I'm experimenting with Coq's standard libraries for integers and rationals. So far my proofs are very time-consuming and look terrible.
    I guess I miss some important proof techniques. Such simple lemmas shouldn't be so long to prove. Any hints?



    Here is an example:



    Require Import ZArith.
    Require Import QArith.
    Open Scope Q_scope.

    Theorem q_less: forall x y z, (0 <= x <= y)%Z -> x # z <= y # z.
    Proof. intros. destruct H as [Hl Hr]. rewrite (Zle_Qle x y) in Hr.
    rewrite <- (Qmult_le_l (inject_Z x) (inject_Z y) (/ inject_Z (Zpos z))) in Hr. simpl in Hr.
    - rewrite Qmult_comm in Hr. rewrite Qmult_comm with (x := / inject_Z (Z.pos z)) in Hr.
    unfold inject_Z in Hr. unfold Qinv in Hr. destruct (Qnum (Z.pos z # 1)) eqn:ZV.
    + simpl in ZV. discriminate.
    + simpl in Hr. simpl in ZV. injection ZV. intro ZP. unfold Qmult in Hr. simpl in Hr.
    rewrite <- ZP in Hr. rewrite Z.mul_1_r in Hr. rewrite Z.mul_1_r in Hr. exact Hr.
    + simpl in ZV. discriminate.
    - unfold Qinv. simpl. apply Z.lt_0_1.
    Qed.









    share|improve this question


























      1












      1








      1








      I'm experimenting with Coq's standard libraries for integers and rationals. So far my proofs are very time-consuming and look terrible.
      I guess I miss some important proof techniques. Such simple lemmas shouldn't be so long to prove. Any hints?



      Here is an example:



      Require Import ZArith.
      Require Import QArith.
      Open Scope Q_scope.

      Theorem q_less: forall x y z, (0 <= x <= y)%Z -> x # z <= y # z.
      Proof. intros. destruct H as [Hl Hr]. rewrite (Zle_Qle x y) in Hr.
      rewrite <- (Qmult_le_l (inject_Z x) (inject_Z y) (/ inject_Z (Zpos z))) in Hr. simpl in Hr.
      - rewrite Qmult_comm in Hr. rewrite Qmult_comm with (x := / inject_Z (Z.pos z)) in Hr.
      unfold inject_Z in Hr. unfold Qinv in Hr. destruct (Qnum (Z.pos z # 1)) eqn:ZV.
      + simpl in ZV. discriminate.
      + simpl in Hr. simpl in ZV. injection ZV. intro ZP. unfold Qmult in Hr. simpl in Hr.
      rewrite <- ZP in Hr. rewrite Z.mul_1_r in Hr. rewrite Z.mul_1_r in Hr. exact Hr.
      + simpl in ZV. discriminate.
      - unfold Qinv. simpl. apply Z.lt_0_1.
      Qed.









      share|improve this question














      I'm experimenting with Coq's standard libraries for integers and rationals. So far my proofs are very time-consuming and look terrible.
      I guess I miss some important proof techniques. Such simple lemmas shouldn't be so long to prove. Any hints?



      Here is an example:



      Require Import ZArith.
      Require Import QArith.
      Open Scope Q_scope.

      Theorem q_less: forall x y z, (0 <= x <= y)%Z -> x # z <= y # z.
      Proof. intros. destruct H as [Hl Hr]. rewrite (Zle_Qle x y) in Hr.
      rewrite <- (Qmult_le_l (inject_Z x) (inject_Z y) (/ inject_Z (Zpos z))) in Hr. simpl in Hr.
      - rewrite Qmult_comm in Hr. rewrite Qmult_comm with (x := / inject_Z (Z.pos z)) in Hr.
      unfold inject_Z in Hr. unfold Qinv in Hr. destruct (Qnum (Z.pos z # 1)) eqn:ZV.
      + simpl in ZV. discriminate.
      + simpl in Hr. simpl in ZV. injection ZV. intro ZP. unfold Qmult in Hr. simpl in Hr.
      rewrite <- ZP in Hr. rewrite Z.mul_1_r in Hr. rewrite Z.mul_1_r in Hr. exact Hr.
      + simpl in ZV. discriminate.
      - unfold Qinv. simpl. apply Z.lt_0_1.
      Qed.






      coq proof rational-number






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 28 at 21:18









      Dmitry VyalDmitry Vyal

      1,6681 gold badge20 silver badges20 bronze badges




      1,6681 gold badge20 silver badges20 bronze badges

























          1 Answer
          1






          active

          oldest

          votes


















          2
















          I did not have the courage to analyze your lengthy proof, but I see you choose to use a forward proof style. The telltale sign is the fact that you have several rewrite ... in ... in your script. Most libraries of theorems are designed to work in backward proof style.



          Contrast this with my proposal for the same proof:



          Theorem q_less: forall x y z, (0 <= x <= y)%Z -> x # z <= y # z.
          Proof.
          intros x y z cmp; rewrite !Qmake_Qdiv.
          apply Qmult_le_compat_r.
          rewrite <- Zle_Qle; tauto.
          apply Qinv_le_0_compat; replace 0 with (inject_Z 0) by easy.
          now rewrite <- Zle_Qle; apply Zle_0_pos.
          Qed.


          Here is how I proceed. First, x # z is a notation for a very specific form of division: the one that appears in a basic fraction. There are many chances that this specific form of division is less well covered by theorems in the library, so I choose to replace it by a regular division between rational numbers. To find the theorem, I just use the Search query with the patterns (_ # _) (_ / _). This gives me Qmake_Qdiv.



          Then I simply expect that there is a theorem expressing a <= b -> a / c <= b / c under suitable conditions. I use Search (_ / _ <= _ / _). to find such a theorem. Alas, none is found. So I remember that division is often described as multiplication by the inverse so I search for the other possibility Search (_ * _ <= _ * _). This gives me Qmult_le_compat_r. I try applying it and it works.



          Here is what I mean by working in a backward proof style: I look at the conclusion and I think what theorem could help me obtain this conclusion? I will then try to fulfill its conditions.



          There are two conditions. The first one is (inject_Z x <= inject_Z y). So now I need a theorem relating comparison in Z and comparison in Q through function inject_Z. To find it I type Search inject_Z (_ <= _). This gives me Qmult_le_compat_r. Please note that your hypothesis is too strong: you don't need x to be positive. The automatic tactic tauto obtains the right condition from your hypothesis (which I named cmp).



          The last condition is (0 <= inject_Z (Z.pos z)). I can re-use the same theorem as above, because surely 0 must be the same thing as inject_Z 0.



          All this being said, I do not recommend using QArith for mathematical reasoning (the kind of algebraic reasoning that you show here), because it is less well populated than other libraries. If you want to work with numbers and reason on them, you should use math-comp or Reals: you will find more theorems that are already proved for you.






          share|improve this answer



























          • thanks for the elaborate explanation. I repeated your steps. Makes sense! How did you acquire such a strategy? Is it just the experience?

            – Dmitry Vyal
            Mar 30 at 7:31











          • I don't remember, I learned by trials and errors, too long ago (28 years). But I remember that in the beginning there were no rewrite ... in ...or apply ... in ... tactics, so that the backward style was practically imposed on you.

            – Yves
            Mar 30 at 18:53












          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );














          draft saved

          draft discarded
















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55406985%2fhow-to-make-algebraic-manipulations-in-coq-easier%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2
















          I did not have the courage to analyze your lengthy proof, but I see you choose to use a forward proof style. The telltale sign is the fact that you have several rewrite ... in ... in your script. Most libraries of theorems are designed to work in backward proof style.



          Contrast this with my proposal for the same proof:



          Theorem q_less: forall x y z, (0 <= x <= y)%Z -> x # z <= y # z.
          Proof.
          intros x y z cmp; rewrite !Qmake_Qdiv.
          apply Qmult_le_compat_r.
          rewrite <- Zle_Qle; tauto.
          apply Qinv_le_0_compat; replace 0 with (inject_Z 0) by easy.
          now rewrite <- Zle_Qle; apply Zle_0_pos.
          Qed.


          Here is how I proceed. First, x # z is a notation for a very specific form of division: the one that appears in a basic fraction. There are many chances that this specific form of division is less well covered by theorems in the library, so I choose to replace it by a regular division between rational numbers. To find the theorem, I just use the Search query with the patterns (_ # _) (_ / _). This gives me Qmake_Qdiv.



          Then I simply expect that there is a theorem expressing a <= b -> a / c <= b / c under suitable conditions. I use Search (_ / _ <= _ / _). to find such a theorem. Alas, none is found. So I remember that division is often described as multiplication by the inverse so I search for the other possibility Search (_ * _ <= _ * _). This gives me Qmult_le_compat_r. I try applying it and it works.



          Here is what I mean by working in a backward proof style: I look at the conclusion and I think what theorem could help me obtain this conclusion? I will then try to fulfill its conditions.



          There are two conditions. The first one is (inject_Z x <= inject_Z y). So now I need a theorem relating comparison in Z and comparison in Q through function inject_Z. To find it I type Search inject_Z (_ <= _). This gives me Qmult_le_compat_r. Please note that your hypothesis is too strong: you don't need x to be positive. The automatic tactic tauto obtains the right condition from your hypothesis (which I named cmp).



          The last condition is (0 <= inject_Z (Z.pos z)). I can re-use the same theorem as above, because surely 0 must be the same thing as inject_Z 0.



          All this being said, I do not recommend using QArith for mathematical reasoning (the kind of algebraic reasoning that you show here), because it is less well populated than other libraries. If you want to work with numbers and reason on them, you should use math-comp or Reals: you will find more theorems that are already proved for you.






          share|improve this answer



























          • thanks for the elaborate explanation. I repeated your steps. Makes sense! How did you acquire such a strategy? Is it just the experience?

            – Dmitry Vyal
            Mar 30 at 7:31











          • I don't remember, I learned by trials and errors, too long ago (28 years). But I remember that in the beginning there were no rewrite ... in ...or apply ... in ... tactics, so that the backward style was practically imposed on you.

            – Yves
            Mar 30 at 18:53















          2
















          I did not have the courage to analyze your lengthy proof, but I see you choose to use a forward proof style. The telltale sign is the fact that you have several rewrite ... in ... in your script. Most libraries of theorems are designed to work in backward proof style.



          Contrast this with my proposal for the same proof:



          Theorem q_less: forall x y z, (0 <= x <= y)%Z -> x # z <= y # z.
          Proof.
          intros x y z cmp; rewrite !Qmake_Qdiv.
          apply Qmult_le_compat_r.
          rewrite <- Zle_Qle; tauto.
          apply Qinv_le_0_compat; replace 0 with (inject_Z 0) by easy.
          now rewrite <- Zle_Qle; apply Zle_0_pos.
          Qed.


          Here is how I proceed. First, x # z is a notation for a very specific form of division: the one that appears in a basic fraction. There are many chances that this specific form of division is less well covered by theorems in the library, so I choose to replace it by a regular division between rational numbers. To find the theorem, I just use the Search query with the patterns (_ # _) (_ / _). This gives me Qmake_Qdiv.



          Then I simply expect that there is a theorem expressing a <= b -> a / c <= b / c under suitable conditions. I use Search (_ / _ <= _ / _). to find such a theorem. Alas, none is found. So I remember that division is often described as multiplication by the inverse so I search for the other possibility Search (_ * _ <= _ * _). This gives me Qmult_le_compat_r. I try applying it and it works.



          Here is what I mean by working in a backward proof style: I look at the conclusion and I think what theorem could help me obtain this conclusion? I will then try to fulfill its conditions.



          There are two conditions. The first one is (inject_Z x <= inject_Z y). So now I need a theorem relating comparison in Z and comparison in Q through function inject_Z. To find it I type Search inject_Z (_ <= _). This gives me Qmult_le_compat_r. Please note that your hypothesis is too strong: you don't need x to be positive. The automatic tactic tauto obtains the right condition from your hypothesis (which I named cmp).



          The last condition is (0 <= inject_Z (Z.pos z)). I can re-use the same theorem as above, because surely 0 must be the same thing as inject_Z 0.



          All this being said, I do not recommend using QArith for mathematical reasoning (the kind of algebraic reasoning that you show here), because it is less well populated than other libraries. If you want to work with numbers and reason on them, you should use math-comp or Reals: you will find more theorems that are already proved for you.






          share|improve this answer



























          • thanks for the elaborate explanation. I repeated your steps. Makes sense! How did you acquire such a strategy? Is it just the experience?

            – Dmitry Vyal
            Mar 30 at 7:31











          • I don't remember, I learned by trials and errors, too long ago (28 years). But I remember that in the beginning there were no rewrite ... in ...or apply ... in ... tactics, so that the backward style was practically imposed on you.

            – Yves
            Mar 30 at 18:53













          2














          2










          2









          I did not have the courage to analyze your lengthy proof, but I see you choose to use a forward proof style. The telltale sign is the fact that you have several rewrite ... in ... in your script. Most libraries of theorems are designed to work in backward proof style.



          Contrast this with my proposal for the same proof:



          Theorem q_less: forall x y z, (0 <= x <= y)%Z -> x # z <= y # z.
          Proof.
          intros x y z cmp; rewrite !Qmake_Qdiv.
          apply Qmult_le_compat_r.
          rewrite <- Zle_Qle; tauto.
          apply Qinv_le_0_compat; replace 0 with (inject_Z 0) by easy.
          now rewrite <- Zle_Qle; apply Zle_0_pos.
          Qed.


          Here is how I proceed. First, x # z is a notation for a very specific form of division: the one that appears in a basic fraction. There are many chances that this specific form of division is less well covered by theorems in the library, so I choose to replace it by a regular division between rational numbers. To find the theorem, I just use the Search query with the patterns (_ # _) (_ / _). This gives me Qmake_Qdiv.



          Then I simply expect that there is a theorem expressing a <= b -> a / c <= b / c under suitable conditions. I use Search (_ / _ <= _ / _). to find such a theorem. Alas, none is found. So I remember that division is often described as multiplication by the inverse so I search for the other possibility Search (_ * _ <= _ * _). This gives me Qmult_le_compat_r. I try applying it and it works.



          Here is what I mean by working in a backward proof style: I look at the conclusion and I think what theorem could help me obtain this conclusion? I will then try to fulfill its conditions.



          There are two conditions. The first one is (inject_Z x <= inject_Z y). So now I need a theorem relating comparison in Z and comparison in Q through function inject_Z. To find it I type Search inject_Z (_ <= _). This gives me Qmult_le_compat_r. Please note that your hypothesis is too strong: you don't need x to be positive. The automatic tactic tauto obtains the right condition from your hypothesis (which I named cmp).



          The last condition is (0 <= inject_Z (Z.pos z)). I can re-use the same theorem as above, because surely 0 must be the same thing as inject_Z 0.



          All this being said, I do not recommend using QArith for mathematical reasoning (the kind of algebraic reasoning that you show here), because it is less well populated than other libraries. If you want to work with numbers and reason on them, you should use math-comp or Reals: you will find more theorems that are already proved for you.






          share|improve this answer















          I did not have the courage to analyze your lengthy proof, but I see you choose to use a forward proof style. The telltale sign is the fact that you have several rewrite ... in ... in your script. Most libraries of theorems are designed to work in backward proof style.



          Contrast this with my proposal for the same proof:



          Theorem q_less: forall x y z, (0 <= x <= y)%Z -> x # z <= y # z.
          Proof.
          intros x y z cmp; rewrite !Qmake_Qdiv.
          apply Qmult_le_compat_r.
          rewrite <- Zle_Qle; tauto.
          apply Qinv_le_0_compat; replace 0 with (inject_Z 0) by easy.
          now rewrite <- Zle_Qle; apply Zle_0_pos.
          Qed.


          Here is how I proceed. First, x # z is a notation for a very specific form of division: the one that appears in a basic fraction. There are many chances that this specific form of division is less well covered by theorems in the library, so I choose to replace it by a regular division between rational numbers. To find the theorem, I just use the Search query with the patterns (_ # _) (_ / _). This gives me Qmake_Qdiv.



          Then I simply expect that there is a theorem expressing a <= b -> a / c <= b / c under suitable conditions. I use Search (_ / _ <= _ / _). to find such a theorem. Alas, none is found. So I remember that division is often described as multiplication by the inverse so I search for the other possibility Search (_ * _ <= _ * _). This gives me Qmult_le_compat_r. I try applying it and it works.



          Here is what I mean by working in a backward proof style: I look at the conclusion and I think what theorem could help me obtain this conclusion? I will then try to fulfill its conditions.



          There are two conditions. The first one is (inject_Z x <= inject_Z y). So now I need a theorem relating comparison in Z and comparison in Q through function inject_Z. To find it I type Search inject_Z (_ <= _). This gives me Qmult_le_compat_r. Please note that your hypothesis is too strong: you don't need x to be positive. The automatic tactic tauto obtains the right condition from your hypothesis (which I named cmp).



          The last condition is (0 <= inject_Z (Z.pos z)). I can re-use the same theorem as above, because surely 0 must be the same thing as inject_Z 0.



          All this being said, I do not recommend using QArith for mathematical reasoning (the kind of algebraic reasoning that you show here), because it is less well populated than other libraries. If you want to work with numbers and reason on them, you should use math-comp or Reals: you will find more theorems that are already proved for you.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 29 at 16:20

























          answered Mar 29 at 16:01









          YvesYves

          2,2287 silver badges11 bronze badges




          2,2287 silver badges11 bronze badges















          • thanks for the elaborate explanation. I repeated your steps. Makes sense! How did you acquire such a strategy? Is it just the experience?

            – Dmitry Vyal
            Mar 30 at 7:31











          • I don't remember, I learned by trials and errors, too long ago (28 years). But I remember that in the beginning there were no rewrite ... in ...or apply ... in ... tactics, so that the backward style was practically imposed on you.

            – Yves
            Mar 30 at 18:53

















          • thanks for the elaborate explanation. I repeated your steps. Makes sense! How did you acquire such a strategy? Is it just the experience?

            – Dmitry Vyal
            Mar 30 at 7:31











          • I don't remember, I learned by trials and errors, too long ago (28 years). But I remember that in the beginning there were no rewrite ... in ...or apply ... in ... tactics, so that the backward style was practically imposed on you.

            – Yves
            Mar 30 at 18:53
















          thanks for the elaborate explanation. I repeated your steps. Makes sense! How did you acquire such a strategy? Is it just the experience?

          – Dmitry Vyal
          Mar 30 at 7:31





          thanks for the elaborate explanation. I repeated your steps. Makes sense! How did you acquire such a strategy? Is it just the experience?

          – Dmitry Vyal
          Mar 30 at 7:31













          I don't remember, I learned by trials and errors, too long ago (28 years). But I remember that in the beginning there were no rewrite ... in ...or apply ... in ... tactics, so that the backward style was practically imposed on you.

          – Yves
          Mar 30 at 18:53





          I don't remember, I learned by trials and errors, too long ago (28 years). But I remember that in the beginning there were no rewrite ... in ...or apply ... in ... tactics, so that the backward style was practically imposed on you.

          – Yves
          Mar 30 at 18:53


















          draft saved

          draft discarded















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55406985%2fhow-to-make-algebraic-manipulations-in-coq-easier%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

          Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

          Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript