Preserving structure with inductions on 2 variables





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I've been learning about Coq's tactics and familiarizing myself with the system by reproving basic facts about natural numbers.



I've been trying to avoid using the theorems that are already proven in the library, and reproving things like the associativity of multiplication, etc.



However, I've been stymied in a couple of cases, where I have a property for n m:nat that I want to prove, but when I try to do induction on both n and m, the structure of the inductive hypothesises is useless for trying to prove the property.



I proved n = m -> o * n = o * m very easily:



Theorem times_alg_left : forall n m o:nat, n = m -> o * n = o * m.
intros n m o H.
rewrite H; reflexivity.
Defined.


But trying to prove S o * n = S o * m -> n = m completely flumoxed me. I decided, after considerable struggles, to try to prove 2 * n = 2 * m -> n = m, but that was no easier.



I end up with situations like this:



Theorem m2_eq : forall n m:nat, 2 * n = 2 * m -> n = m.
intros n m H.
induction n.
destruct m.
reflexivity.
discriminate.
induction m.
discriminate.

1 subgoal
n, m : nat
H : 2 * S n = 2 * S m
IHn : 2 * n = 2 * S m -> n = S m
IHm : 2 * S n = 2 * m -> (2 * n = 2 * m -> n = m) -> S n = m
______________________________________(1/1)
S n = S m


I've got 2 * S n = 2 * S m, but my inductive premises are talking about 2 * n = 2 * S m and 2 * S n = 2 * m.



I can't make anything happen from this situation.



Similarly, I started trying to proof things about Nat.sub and less than or equal to get around this limitation, but I ran into the same situation.



Theorem sub0_imp_le : forall n m:nat, n - m = 0 -> n <= m.
intros n m H.
induction n; induction m.
apply le_n.
apply le_0.
rewrite sub0 in H.
discriminate.

1 subgoal
n, m : nat
H : S n - S m = 0
IHn : n - S m = 0 -> n <= S m
IHm : S n - m = 0 -> (n - m = 0 -> n <= m) -> S n <= m
______________________________________(1/1)
S n <= S m


But I'm in the same pickle where my inductive premises are worthless.



How do I structure my tactics to solve these type of theorems, with 2 nat variables, and some kind of equality or subtraction situation going on?










share|improve this question





























    1















    I've been learning about Coq's tactics and familiarizing myself with the system by reproving basic facts about natural numbers.



    I've been trying to avoid using the theorems that are already proven in the library, and reproving things like the associativity of multiplication, etc.



    However, I've been stymied in a couple of cases, where I have a property for n m:nat that I want to prove, but when I try to do induction on both n and m, the structure of the inductive hypothesises is useless for trying to prove the property.



    I proved n = m -> o * n = o * m very easily:



    Theorem times_alg_left : forall n m o:nat, n = m -> o * n = o * m.
    intros n m o H.
    rewrite H; reflexivity.
    Defined.


    But trying to prove S o * n = S o * m -> n = m completely flumoxed me. I decided, after considerable struggles, to try to prove 2 * n = 2 * m -> n = m, but that was no easier.



    I end up with situations like this:



    Theorem m2_eq : forall n m:nat, 2 * n = 2 * m -> n = m.
    intros n m H.
    induction n.
    destruct m.
    reflexivity.
    discriminate.
    induction m.
    discriminate.

    1 subgoal
    n, m : nat
    H : 2 * S n = 2 * S m
    IHn : 2 * n = 2 * S m -> n = S m
    IHm : 2 * S n = 2 * m -> (2 * n = 2 * m -> n = m) -> S n = m
    ______________________________________(1/1)
    S n = S m


    I've got 2 * S n = 2 * S m, but my inductive premises are talking about 2 * n = 2 * S m and 2 * S n = 2 * m.



    I can't make anything happen from this situation.



    Similarly, I started trying to proof things about Nat.sub and less than or equal to get around this limitation, but I ran into the same situation.



    Theorem sub0_imp_le : forall n m:nat, n - m = 0 -> n <= m.
    intros n m H.
    induction n; induction m.
    apply le_n.
    apply le_0.
    rewrite sub0 in H.
    discriminate.

    1 subgoal
    n, m : nat
    H : S n - S m = 0
    IHn : n - S m = 0 -> n <= S m
    IHm : S n - m = 0 -> (n - m = 0 -> n <= m) -> S n <= m
    ______________________________________(1/1)
    S n <= S m


    But I'm in the same pickle where my inductive premises are worthless.



    How do I structure my tactics to solve these type of theorems, with 2 nat variables, and some kind of equality or subtraction situation going on?










    share|improve this question

























      1












      1








      1








      I've been learning about Coq's tactics and familiarizing myself with the system by reproving basic facts about natural numbers.



      I've been trying to avoid using the theorems that are already proven in the library, and reproving things like the associativity of multiplication, etc.



      However, I've been stymied in a couple of cases, where I have a property for n m:nat that I want to prove, but when I try to do induction on both n and m, the structure of the inductive hypothesises is useless for trying to prove the property.



      I proved n = m -> o * n = o * m very easily:



      Theorem times_alg_left : forall n m o:nat, n = m -> o * n = o * m.
      intros n m o H.
      rewrite H; reflexivity.
      Defined.


      But trying to prove S o * n = S o * m -> n = m completely flumoxed me. I decided, after considerable struggles, to try to prove 2 * n = 2 * m -> n = m, but that was no easier.



      I end up with situations like this:



      Theorem m2_eq : forall n m:nat, 2 * n = 2 * m -> n = m.
      intros n m H.
      induction n.
      destruct m.
      reflexivity.
      discriminate.
      induction m.
      discriminate.

      1 subgoal
      n, m : nat
      H : 2 * S n = 2 * S m
      IHn : 2 * n = 2 * S m -> n = S m
      IHm : 2 * S n = 2 * m -> (2 * n = 2 * m -> n = m) -> S n = m
      ______________________________________(1/1)
      S n = S m


      I've got 2 * S n = 2 * S m, but my inductive premises are talking about 2 * n = 2 * S m and 2 * S n = 2 * m.



      I can't make anything happen from this situation.



      Similarly, I started trying to proof things about Nat.sub and less than or equal to get around this limitation, but I ran into the same situation.



      Theorem sub0_imp_le : forall n m:nat, n - m = 0 -> n <= m.
      intros n m H.
      induction n; induction m.
      apply le_n.
      apply le_0.
      rewrite sub0 in H.
      discriminate.

      1 subgoal
      n, m : nat
      H : S n - S m = 0
      IHn : n - S m = 0 -> n <= S m
      IHm : S n - m = 0 -> (n - m = 0 -> n <= m) -> S n <= m
      ______________________________________(1/1)
      S n <= S m


      But I'm in the same pickle where my inductive premises are worthless.



      How do I structure my tactics to solve these type of theorems, with 2 nat variables, and some kind of equality or subtraction situation going on?










      share|improve this question














      I've been learning about Coq's tactics and familiarizing myself with the system by reproving basic facts about natural numbers.



      I've been trying to avoid using the theorems that are already proven in the library, and reproving things like the associativity of multiplication, etc.



      However, I've been stymied in a couple of cases, where I have a property for n m:nat that I want to prove, but when I try to do induction on both n and m, the structure of the inductive hypothesises is useless for trying to prove the property.



      I proved n = m -> o * n = o * m very easily:



      Theorem times_alg_left : forall n m o:nat, n = m -> o * n = o * m.
      intros n m o H.
      rewrite H; reflexivity.
      Defined.


      But trying to prove S o * n = S o * m -> n = m completely flumoxed me. I decided, after considerable struggles, to try to prove 2 * n = 2 * m -> n = m, but that was no easier.



      I end up with situations like this:



      Theorem m2_eq : forall n m:nat, 2 * n = 2 * m -> n = m.
      intros n m H.
      induction n.
      destruct m.
      reflexivity.
      discriminate.
      induction m.
      discriminate.

      1 subgoal
      n, m : nat
      H : 2 * S n = 2 * S m
      IHn : 2 * n = 2 * S m -> n = S m
      IHm : 2 * S n = 2 * m -> (2 * n = 2 * m -> n = m) -> S n = m
      ______________________________________(1/1)
      S n = S m


      I've got 2 * S n = 2 * S m, but my inductive premises are talking about 2 * n = 2 * S m and 2 * S n = 2 * m.



      I can't make anything happen from this situation.



      Similarly, I started trying to proof things about Nat.sub and less than or equal to get around this limitation, but I ran into the same situation.



      Theorem sub0_imp_le : forall n m:nat, n - m = 0 -> n <= m.
      intros n m H.
      induction n; induction m.
      apply le_n.
      apply le_0.
      rewrite sub0 in H.
      discriminate.

      1 subgoal
      n, m : nat
      H : S n - S m = 0
      IHn : n - S m = 0 -> n <= S m
      IHm : S n - m = 0 -> (n - m = 0 -> n <= m) -> S n <= m
      ______________________________________(1/1)
      S n <= S m


      But I'm in the same pickle where my inductive premises are worthless.



      How do I structure my tactics to solve these type of theorems, with 2 nat variables, and some kind of equality or subtraction situation going on?







      coq coq-tactic






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 16 '18 at 13:56









      Tony PetersonTony Peterson

      7,775134164




      7,775134164
























          2 Answers
          2






          active

          oldest

          votes


















          1














          You need to do induct on one number while generalizing the other, using the generalize dependent tactic, for instance. This is explained in detail in the Software Foundations book.






          share|improve this answer
























          • I thought the Software Foundations book was going to be just about writing programs using Coq. Looks like its a valuable resource in general. I'll take a look.

            – Tony Peterson
            Nov 16 '18 at 14:34



















          0














          Using the Software Foundations book Arthur mentioned, I found the exmaple in question. I need to not introduce m before doing induction on n. I needed to do induction on n first instead, then introduce m.



          https://softwarefoundations.cis.upenn.edu/lf-current/Tactics.html#lab143



          Theorem times_alg_rem_left : forall n o m:nat, (S o) * n = (S o) * m -> n = m.
          intros n o.
          induction n.
          simpl.
          intros m eq.
          destruct m.
          reflexivity.
          rewrite (timesz o) in eq.
          simpl in eq.
          discriminate.
          intros m eq.
          destruct m.
          rewrite (timesz (S o)) in eq.
          inversion eq.
          apply f_equal.
          apply IHn.
          rewrite (times_nSm (S o) n) in eq.
          rewrite (times_nSm (S o) m) in eq.
          apply plus_alg_rem_right in eq.
          assumption.
          Defined.





          share|improve this answer
























            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/3.0/"u003ecc by-sa 3.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%2f53339267%2fpreserving-structure-with-inductions-on-2-variables%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            You need to do induct on one number while generalizing the other, using the generalize dependent tactic, for instance. This is explained in detail in the Software Foundations book.






            share|improve this answer
























            • I thought the Software Foundations book was going to be just about writing programs using Coq. Looks like its a valuable resource in general. I'll take a look.

              – Tony Peterson
              Nov 16 '18 at 14:34
















            1














            You need to do induct on one number while generalizing the other, using the generalize dependent tactic, for instance. This is explained in detail in the Software Foundations book.






            share|improve this answer
























            • I thought the Software Foundations book was going to be just about writing programs using Coq. Looks like its a valuable resource in general. I'll take a look.

              – Tony Peterson
              Nov 16 '18 at 14:34














            1












            1








            1







            You need to do induct on one number while generalizing the other, using the generalize dependent tactic, for instance. This is explained in detail in the Software Foundations book.






            share|improve this answer













            You need to do induct on one number while generalizing the other, using the generalize dependent tactic, for instance. This is explained in detail in the Software Foundations book.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 16 '18 at 14:24









            Arthur Azevedo De AmorimArthur Azevedo De Amorim

            14.9k21725




            14.9k21725













            • I thought the Software Foundations book was going to be just about writing programs using Coq. Looks like its a valuable resource in general. I'll take a look.

              – Tony Peterson
              Nov 16 '18 at 14:34



















            • I thought the Software Foundations book was going to be just about writing programs using Coq. Looks like its a valuable resource in general. I'll take a look.

              – Tony Peterson
              Nov 16 '18 at 14:34

















            I thought the Software Foundations book was going to be just about writing programs using Coq. Looks like its a valuable resource in general. I'll take a look.

            – Tony Peterson
            Nov 16 '18 at 14:34





            I thought the Software Foundations book was going to be just about writing programs using Coq. Looks like its a valuable resource in general. I'll take a look.

            – Tony Peterson
            Nov 16 '18 at 14:34













            0














            Using the Software Foundations book Arthur mentioned, I found the exmaple in question. I need to not introduce m before doing induction on n. I needed to do induction on n first instead, then introduce m.



            https://softwarefoundations.cis.upenn.edu/lf-current/Tactics.html#lab143



            Theorem times_alg_rem_left : forall n o m:nat, (S o) * n = (S o) * m -> n = m.
            intros n o.
            induction n.
            simpl.
            intros m eq.
            destruct m.
            reflexivity.
            rewrite (timesz o) in eq.
            simpl in eq.
            discriminate.
            intros m eq.
            destruct m.
            rewrite (timesz (S o)) in eq.
            inversion eq.
            apply f_equal.
            apply IHn.
            rewrite (times_nSm (S o) n) in eq.
            rewrite (times_nSm (S o) m) in eq.
            apply plus_alg_rem_right in eq.
            assumption.
            Defined.





            share|improve this answer




























              0














              Using the Software Foundations book Arthur mentioned, I found the exmaple in question. I need to not introduce m before doing induction on n. I needed to do induction on n first instead, then introduce m.



              https://softwarefoundations.cis.upenn.edu/lf-current/Tactics.html#lab143



              Theorem times_alg_rem_left : forall n o m:nat, (S o) * n = (S o) * m -> n = m.
              intros n o.
              induction n.
              simpl.
              intros m eq.
              destruct m.
              reflexivity.
              rewrite (timesz o) in eq.
              simpl in eq.
              discriminate.
              intros m eq.
              destruct m.
              rewrite (timesz (S o)) in eq.
              inversion eq.
              apply f_equal.
              apply IHn.
              rewrite (times_nSm (S o) n) in eq.
              rewrite (times_nSm (S o) m) in eq.
              apply plus_alg_rem_right in eq.
              assumption.
              Defined.





              share|improve this answer


























                0












                0








                0







                Using the Software Foundations book Arthur mentioned, I found the exmaple in question. I need to not introduce m before doing induction on n. I needed to do induction on n first instead, then introduce m.



                https://softwarefoundations.cis.upenn.edu/lf-current/Tactics.html#lab143



                Theorem times_alg_rem_left : forall n o m:nat, (S o) * n = (S o) * m -> n = m.
                intros n o.
                induction n.
                simpl.
                intros m eq.
                destruct m.
                reflexivity.
                rewrite (timesz o) in eq.
                simpl in eq.
                discriminate.
                intros m eq.
                destruct m.
                rewrite (timesz (S o)) in eq.
                inversion eq.
                apply f_equal.
                apply IHn.
                rewrite (times_nSm (S o) n) in eq.
                rewrite (times_nSm (S o) m) in eq.
                apply plus_alg_rem_right in eq.
                assumption.
                Defined.





                share|improve this answer













                Using the Software Foundations book Arthur mentioned, I found the exmaple in question. I need to not introduce m before doing induction on n. I needed to do induction on n first instead, then introduce m.



                https://softwarefoundations.cis.upenn.edu/lf-current/Tactics.html#lab143



                Theorem times_alg_rem_left : forall n o m:nat, (S o) * n = (S o) * m -> n = m.
                intros n o.
                induction n.
                simpl.
                intros m eq.
                destruct m.
                reflexivity.
                rewrite (timesz o) in eq.
                simpl in eq.
                discriminate.
                intros m eq.
                destruct m.
                rewrite (timesz (S o)) in eq.
                inversion eq.
                apply f_equal.
                apply IHn.
                rewrite (times_nSm (S o) n) in eq.
                rewrite (times_nSm (S o) m) in eq.
                apply plus_alg_rem_right in eq.
                assumption.
                Defined.






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 16 '18 at 15:02









                Tony PetersonTony Peterson

                7,775134164




                7,775134164






























                    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%2f53339267%2fpreserving-structure-with-inductions-on-2-variables%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

                    Xamarin.iOS Cant Deploy on Iphone

                    Glorious Revolution

                    Dulmage-Mendelsohn matrix decomposition in Python