Lean Mergesort using increasing well founded relation












3















I am trying to create the mergesort definition in Lean and have created the following code:



def mergesort (a: ℕ): list ℕ → list ℕ     
| :=
| [a] := [a]
| (x::xs) := merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


With the merge definition



def merge : list ℕ → list ℕ → list ℕ    
| xs := xs
| ys := ys
| (x :: xs) (y :: ys) := if x < y then x :: (merge xs ( y :: ys))
else y :: (merge (x :: xs) ys)


And fhalf / sndhalf definitions:



 def fhalf {α: Type} (xs: list α): list α := 
list.take (list.length xs/2) xs

def sndhalf {α: Type} (xs: list α): list α :=
list.drop (list.length xs/2) xs


However, I get the following error message:




failed to prove recursive application is decreasing, well founded
relation



@has_well_founded.r (list ℕ)
(@has_well_founded_of_has_sizeof (list ℕ) (@list.has_sizeof ℕ nat.has_sizeof))


Possible solutions:




  • Use using_well_founded keyword in the end of your definition to specify tactics for synthesizing well founded relations and decreasing proofs.


  • The default decreasing tactic uses the 'assumption' tactic, thus hints (aka local proofs) can be provided using 'have'-expressions. The nested exception contains the failure state for the decreasing tactic.





Can anyone help me to prove that the mergesort is decreasing?










share|improve this question

























  • Can you explain what you mean by "increasing definition"?

    – Mark Dickinson
    Jan 2 at 18:48











  • BTW, your definition of mergesort doesn't look quite right: it looks as though you're throwing away the x at the head of the list. And do you have your definitions of fhalf and sndhalf available?

    – Mark Dickinson
    Jan 2 at 19:00













  • I have edited my question. I meant to prove that the mergesort is indeed decreasing properly. The problem occurs when I use the list.take and list.drop functions within the definition.

    – Kjell Zijlemaker
    Jan 3 at 12:59











  • Have you tried list.partition? It translates more naturally to the notion of a deterministic base case (aka decreasing ...).

    – Funk
    Jan 3 at 14:45


















3















I am trying to create the mergesort definition in Lean and have created the following code:



def mergesort (a: ℕ): list ℕ → list ℕ     
| :=
| [a] := [a]
| (x::xs) := merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


With the merge definition



def merge : list ℕ → list ℕ → list ℕ    
| xs := xs
| ys := ys
| (x :: xs) (y :: ys) := if x < y then x :: (merge xs ( y :: ys))
else y :: (merge (x :: xs) ys)


And fhalf / sndhalf definitions:



 def fhalf {α: Type} (xs: list α): list α := 
list.take (list.length xs/2) xs

def sndhalf {α: Type} (xs: list α): list α :=
list.drop (list.length xs/2) xs


However, I get the following error message:




failed to prove recursive application is decreasing, well founded
relation



@has_well_founded.r (list ℕ)
(@has_well_founded_of_has_sizeof (list ℕ) (@list.has_sizeof ℕ nat.has_sizeof))


Possible solutions:




  • Use using_well_founded keyword in the end of your definition to specify tactics for synthesizing well founded relations and decreasing proofs.


  • The default decreasing tactic uses the 'assumption' tactic, thus hints (aka local proofs) can be provided using 'have'-expressions. The nested exception contains the failure state for the decreasing tactic.





Can anyone help me to prove that the mergesort is decreasing?










share|improve this question

























  • Can you explain what you mean by "increasing definition"?

    – Mark Dickinson
    Jan 2 at 18:48











  • BTW, your definition of mergesort doesn't look quite right: it looks as though you're throwing away the x at the head of the list. And do you have your definitions of fhalf and sndhalf available?

    – Mark Dickinson
    Jan 2 at 19:00













  • I have edited my question. I meant to prove that the mergesort is indeed decreasing properly. The problem occurs when I use the list.take and list.drop functions within the definition.

    – Kjell Zijlemaker
    Jan 3 at 12:59











  • Have you tried list.partition? It translates more naturally to the notion of a deterministic base case (aka decreasing ...).

    – Funk
    Jan 3 at 14:45
















3












3








3








I am trying to create the mergesort definition in Lean and have created the following code:



def mergesort (a: ℕ): list ℕ → list ℕ     
| :=
| [a] := [a]
| (x::xs) := merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


With the merge definition



def merge : list ℕ → list ℕ → list ℕ    
| xs := xs
| ys := ys
| (x :: xs) (y :: ys) := if x < y then x :: (merge xs ( y :: ys))
else y :: (merge (x :: xs) ys)


And fhalf / sndhalf definitions:



 def fhalf {α: Type} (xs: list α): list α := 
list.take (list.length xs/2) xs

def sndhalf {α: Type} (xs: list α): list α :=
list.drop (list.length xs/2) xs


However, I get the following error message:




failed to prove recursive application is decreasing, well founded
relation



@has_well_founded.r (list ℕ)
(@has_well_founded_of_has_sizeof (list ℕ) (@list.has_sizeof ℕ nat.has_sizeof))


Possible solutions:




  • Use using_well_founded keyword in the end of your definition to specify tactics for synthesizing well founded relations and decreasing proofs.


  • The default decreasing tactic uses the 'assumption' tactic, thus hints (aka local proofs) can be provided using 'have'-expressions. The nested exception contains the failure state for the decreasing tactic.





Can anyone help me to prove that the mergesort is decreasing?










share|improve this question
















I am trying to create the mergesort definition in Lean and have created the following code:



def mergesort (a: ℕ): list ℕ → list ℕ     
| :=
| [a] := [a]
| (x::xs) := merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


With the merge definition



def merge : list ℕ → list ℕ → list ℕ    
| xs := xs
| ys := ys
| (x :: xs) (y :: ys) := if x < y then x :: (merge xs ( y :: ys))
else y :: (merge (x :: xs) ys)


And fhalf / sndhalf definitions:



 def fhalf {α: Type} (xs: list α): list α := 
list.take (list.length xs/2) xs

def sndhalf {α: Type} (xs: list α): list α :=
list.drop (list.length xs/2) xs


However, I get the following error message:




failed to prove recursive application is decreasing, well founded
relation



@has_well_founded.r (list ℕ)
(@has_well_founded_of_has_sizeof (list ℕ) (@list.has_sizeof ℕ nat.has_sizeof))


Possible solutions:




  • Use using_well_founded keyword in the end of your definition to specify tactics for synthesizing well founded relations and decreasing proofs.


  • The default decreasing tactic uses the 'assumption' tactic, thus hints (aka local proofs) can be provided using 'have'-expressions. The nested exception contains the failure state for the decreasing tactic.





Can anyone help me to prove that the mergesort is decreasing?







algorithm mergesort lean






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 12:58







Kjell Zijlemaker

















asked Dec 30 '18 at 11:44









Kjell ZijlemakerKjell Zijlemaker

144210




144210













  • Can you explain what you mean by "increasing definition"?

    – Mark Dickinson
    Jan 2 at 18:48











  • BTW, your definition of mergesort doesn't look quite right: it looks as though you're throwing away the x at the head of the list. And do you have your definitions of fhalf and sndhalf available?

    – Mark Dickinson
    Jan 2 at 19:00













  • I have edited my question. I meant to prove that the mergesort is indeed decreasing properly. The problem occurs when I use the list.take and list.drop functions within the definition.

    – Kjell Zijlemaker
    Jan 3 at 12:59











  • Have you tried list.partition? It translates more naturally to the notion of a deterministic base case (aka decreasing ...).

    – Funk
    Jan 3 at 14:45





















  • Can you explain what you mean by "increasing definition"?

    – Mark Dickinson
    Jan 2 at 18:48











  • BTW, your definition of mergesort doesn't look quite right: it looks as though you're throwing away the x at the head of the list. And do you have your definitions of fhalf and sndhalf available?

    – Mark Dickinson
    Jan 2 at 19:00













  • I have edited my question. I meant to prove that the mergesort is indeed decreasing properly. The problem occurs when I use the list.take and list.drop functions within the definition.

    – Kjell Zijlemaker
    Jan 3 at 12:59











  • Have you tried list.partition? It translates more naturally to the notion of a deterministic base case (aka decreasing ...).

    – Funk
    Jan 3 at 14:45



















Can you explain what you mean by "increasing definition"?

– Mark Dickinson
Jan 2 at 18:48





Can you explain what you mean by "increasing definition"?

– Mark Dickinson
Jan 2 at 18:48













BTW, your definition of mergesort doesn't look quite right: it looks as though you're throwing away the x at the head of the list. And do you have your definitions of fhalf and sndhalf available?

– Mark Dickinson
Jan 2 at 19:00







BTW, your definition of mergesort doesn't look quite right: it looks as though you're throwing away the x at the head of the list. And do you have your definitions of fhalf and sndhalf available?

– Mark Dickinson
Jan 2 at 19:00















I have edited my question. I meant to prove that the mergesort is indeed decreasing properly. The problem occurs when I use the list.take and list.drop functions within the definition.

– Kjell Zijlemaker
Jan 3 at 12:59





I have edited my question. I meant to prove that the mergesort is indeed decreasing properly. The problem occurs when I use the list.take and list.drop functions within the definition.

– Kjell Zijlemaker
Jan 3 at 12:59













Have you tried list.partition? It translates more naturally to the notion of a deterministic base case (aka decreasing ...).

– Funk
Jan 3 at 14:45







Have you tried list.partition? It translates more naturally to the notion of a deterministic base case (aka decreasing ...).

– Funk
Jan 3 at 14:45














1 Answer
1






active

oldest

votes


















4





+50









First, notice that there are multiple problems with your definition of mergesort. One, the parameter a is unnecessary and never used. (The a that you match in the second line is fresh.) Two, in the x::xs case, you forget about x entirely. To see what your function is actually doing, you can add the keyword meta, as in meta def mergesort. This disables termination checking, so then you can #eval mergesort 2 [1, 3, 2] and see that you do not get what you want. I'll continue to answer this as you've written it.



There is a default well-founded relation, and the default method for proving it is to look for proofs in the local context. You can see what proofs Lean is expecting by looking at the error messages in your definition: it wants proofs of list.sizeof (fhalf xs) < x + (1 + list.sizeof xs) and list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs). So by adding lines



def mergesort (a : ℕ): list ℕ → list ℕ     
| :=
| [a] := [a]
| (x::xs) :=
have list.sizeof (fhalf xs) < x + (1 + list.sizeof xs), from sorry,
have list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs), from sorry,
merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


this strategy will succeed. You need to fill in those sorrys.



Using the linarith tactic available in mathlib (via import tactic.linarith) you can skip some arithmetic:



def mergesort (a : ℕ): list ℕ → list ℕ     
| :=
| [a] := [a]
| (x::xs) :=
have list.sizeof (fhalf xs) ≤ list.sizeof xs, from sorry,
have list.sizeof (sndhalf xs) ≤ list.sizeof xs, from sorry,
have list.sizeof (fhalf xs) < x + (1 + list.sizeof xs), by linarith,
have list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs), by linarith,
merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


So replace those sorrys with proofs, and you're good to go. You probably want to prove something like



lemma sizeof_take_le {α} [h : has_sizeof α] : ∀ n (xs : list α), 
list.sizeof (list.take n xs) ≤ list.sizeof xs


The details will change a little when you correct your definition of mergesort.



An alternative approach is to change the well founded relation and decision tactic, as is done in the mathlib definition: https://github.com/leanprover/mathlib/blob/master/data/list/sort.lean#L174
Unfortunately, the interface for doing this is rather low-level and I don't know if or where it's documented.



To change the relation without using_well_founded, you could add a local instance that says to use list.length instead of list.sizeof:



def new_list_sizeof : has_sizeof (list ℕ) := ⟨list.length⟩
local attribute [instance, priority 100000] new_list_sizeof


The goals that this produces will be easier for you to prove than those using sizeof.






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%2f53977313%2flean-mergesort-using-increasing-well-founded-relation%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









    4





    +50









    First, notice that there are multiple problems with your definition of mergesort. One, the parameter a is unnecessary and never used. (The a that you match in the second line is fresh.) Two, in the x::xs case, you forget about x entirely. To see what your function is actually doing, you can add the keyword meta, as in meta def mergesort. This disables termination checking, so then you can #eval mergesort 2 [1, 3, 2] and see that you do not get what you want. I'll continue to answer this as you've written it.



    There is a default well-founded relation, and the default method for proving it is to look for proofs in the local context. You can see what proofs Lean is expecting by looking at the error messages in your definition: it wants proofs of list.sizeof (fhalf xs) < x + (1 + list.sizeof xs) and list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs). So by adding lines



    def mergesort (a : ℕ): list ℕ → list ℕ     
    | :=
    | [a] := [a]
    | (x::xs) :=
    have list.sizeof (fhalf xs) < x + (1 + list.sizeof xs), from sorry,
    have list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs), from sorry,
    merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


    this strategy will succeed. You need to fill in those sorrys.



    Using the linarith tactic available in mathlib (via import tactic.linarith) you can skip some arithmetic:



    def mergesort (a : ℕ): list ℕ → list ℕ     
    | :=
    | [a] := [a]
    | (x::xs) :=
    have list.sizeof (fhalf xs) ≤ list.sizeof xs, from sorry,
    have list.sizeof (sndhalf xs) ≤ list.sizeof xs, from sorry,
    have list.sizeof (fhalf xs) < x + (1 + list.sizeof xs), by linarith,
    have list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs), by linarith,
    merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


    So replace those sorrys with proofs, and you're good to go. You probably want to prove something like



    lemma sizeof_take_le {α} [h : has_sizeof α] : ∀ n (xs : list α), 
    list.sizeof (list.take n xs) ≤ list.sizeof xs


    The details will change a little when you correct your definition of mergesort.



    An alternative approach is to change the well founded relation and decision tactic, as is done in the mathlib definition: https://github.com/leanprover/mathlib/blob/master/data/list/sort.lean#L174
    Unfortunately, the interface for doing this is rather low-level and I don't know if or where it's documented.



    To change the relation without using_well_founded, you could add a local instance that says to use list.length instead of list.sizeof:



    def new_list_sizeof : has_sizeof (list ℕ) := ⟨list.length⟩
    local attribute [instance, priority 100000] new_list_sizeof


    The goals that this produces will be easier for you to prove than those using sizeof.






    share|improve this answer






























      4





      +50









      First, notice that there are multiple problems with your definition of mergesort. One, the parameter a is unnecessary and never used. (The a that you match in the second line is fresh.) Two, in the x::xs case, you forget about x entirely. To see what your function is actually doing, you can add the keyword meta, as in meta def mergesort. This disables termination checking, so then you can #eval mergesort 2 [1, 3, 2] and see that you do not get what you want. I'll continue to answer this as you've written it.



      There is a default well-founded relation, and the default method for proving it is to look for proofs in the local context. You can see what proofs Lean is expecting by looking at the error messages in your definition: it wants proofs of list.sizeof (fhalf xs) < x + (1 + list.sizeof xs) and list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs). So by adding lines



      def mergesort (a : ℕ): list ℕ → list ℕ     
      | :=
      | [a] := [a]
      | (x::xs) :=
      have list.sizeof (fhalf xs) < x + (1 + list.sizeof xs), from sorry,
      have list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs), from sorry,
      merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


      this strategy will succeed. You need to fill in those sorrys.



      Using the linarith tactic available in mathlib (via import tactic.linarith) you can skip some arithmetic:



      def mergesort (a : ℕ): list ℕ → list ℕ     
      | :=
      | [a] := [a]
      | (x::xs) :=
      have list.sizeof (fhalf xs) ≤ list.sizeof xs, from sorry,
      have list.sizeof (sndhalf xs) ≤ list.sizeof xs, from sorry,
      have list.sizeof (fhalf xs) < x + (1 + list.sizeof xs), by linarith,
      have list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs), by linarith,
      merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


      So replace those sorrys with proofs, and you're good to go. You probably want to prove something like



      lemma sizeof_take_le {α} [h : has_sizeof α] : ∀ n (xs : list α), 
      list.sizeof (list.take n xs) ≤ list.sizeof xs


      The details will change a little when you correct your definition of mergesort.



      An alternative approach is to change the well founded relation and decision tactic, as is done in the mathlib definition: https://github.com/leanprover/mathlib/blob/master/data/list/sort.lean#L174
      Unfortunately, the interface for doing this is rather low-level and I don't know if or where it's documented.



      To change the relation without using_well_founded, you could add a local instance that says to use list.length instead of list.sizeof:



      def new_list_sizeof : has_sizeof (list ℕ) := ⟨list.length⟩
      local attribute [instance, priority 100000] new_list_sizeof


      The goals that this produces will be easier for you to prove than those using sizeof.






      share|improve this answer




























        4





        +50







        4





        +50



        4




        +50





        First, notice that there are multiple problems with your definition of mergesort. One, the parameter a is unnecessary and never used. (The a that you match in the second line is fresh.) Two, in the x::xs case, you forget about x entirely. To see what your function is actually doing, you can add the keyword meta, as in meta def mergesort. This disables termination checking, so then you can #eval mergesort 2 [1, 3, 2] and see that you do not get what you want. I'll continue to answer this as you've written it.



        There is a default well-founded relation, and the default method for proving it is to look for proofs in the local context. You can see what proofs Lean is expecting by looking at the error messages in your definition: it wants proofs of list.sizeof (fhalf xs) < x + (1 + list.sizeof xs) and list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs). So by adding lines



        def mergesort (a : ℕ): list ℕ → list ℕ     
        | :=
        | [a] := [a]
        | (x::xs) :=
        have list.sizeof (fhalf xs) < x + (1 + list.sizeof xs), from sorry,
        have list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs), from sorry,
        merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


        this strategy will succeed. You need to fill in those sorrys.



        Using the linarith tactic available in mathlib (via import tactic.linarith) you can skip some arithmetic:



        def mergesort (a : ℕ): list ℕ → list ℕ     
        | :=
        | [a] := [a]
        | (x::xs) :=
        have list.sizeof (fhalf xs) ≤ list.sizeof xs, from sorry,
        have list.sizeof (sndhalf xs) ≤ list.sizeof xs, from sorry,
        have list.sizeof (fhalf xs) < x + (1 + list.sizeof xs), by linarith,
        have list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs), by linarith,
        merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


        So replace those sorrys with proofs, and you're good to go. You probably want to prove something like



        lemma sizeof_take_le {α} [h : has_sizeof α] : ∀ n (xs : list α), 
        list.sizeof (list.take n xs) ≤ list.sizeof xs


        The details will change a little when you correct your definition of mergesort.



        An alternative approach is to change the well founded relation and decision tactic, as is done in the mathlib definition: https://github.com/leanprover/mathlib/blob/master/data/list/sort.lean#L174
        Unfortunately, the interface for doing this is rather low-level and I don't know if or where it's documented.



        To change the relation without using_well_founded, you could add a local instance that says to use list.length instead of list.sizeof:



        def new_list_sizeof : has_sizeof (list ℕ) := ⟨list.length⟩
        local attribute [instance, priority 100000] new_list_sizeof


        The goals that this produces will be easier for you to prove than those using sizeof.






        share|improve this answer















        First, notice that there are multiple problems with your definition of mergesort. One, the parameter a is unnecessary and never used. (The a that you match in the second line is fresh.) Two, in the x::xs case, you forget about x entirely. To see what your function is actually doing, you can add the keyword meta, as in meta def mergesort. This disables termination checking, so then you can #eval mergesort 2 [1, 3, 2] and see that you do not get what you want. I'll continue to answer this as you've written it.



        There is a default well-founded relation, and the default method for proving it is to look for proofs in the local context. You can see what proofs Lean is expecting by looking at the error messages in your definition: it wants proofs of list.sizeof (fhalf xs) < x + (1 + list.sizeof xs) and list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs). So by adding lines



        def mergesort (a : ℕ): list ℕ → list ℕ     
        | :=
        | [a] := [a]
        | (x::xs) :=
        have list.sizeof (fhalf xs) < x + (1 + list.sizeof xs), from sorry,
        have list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs), from sorry,
        merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


        this strategy will succeed. You need to fill in those sorrys.



        Using the linarith tactic available in mathlib (via import tactic.linarith) you can skip some arithmetic:



        def mergesort (a : ℕ): list ℕ → list ℕ     
        | :=
        | [a] := [a]
        | (x::xs) :=
        have list.sizeof (fhalf xs) ≤ list.sizeof xs, from sorry,
        have list.sizeof (sndhalf xs) ≤ list.sizeof xs, from sorry,
        have list.sizeof (fhalf xs) < x + (1 + list.sizeof xs), by linarith,
        have list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs), by linarith,
        merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))


        So replace those sorrys with proofs, and you're good to go. You probably want to prove something like



        lemma sizeof_take_le {α} [h : has_sizeof α] : ∀ n (xs : list α), 
        list.sizeof (list.take n xs) ≤ list.sizeof xs


        The details will change a little when you correct your definition of mergesort.



        An alternative approach is to change the well founded relation and decision tactic, as is done in the mathlib definition: https://github.com/leanprover/mathlib/blob/master/data/list/sort.lean#L174
        Unfortunately, the interface for doing this is rather low-level and I don't know if or where it's documented.



        To change the relation without using_well_founded, you could add a local instance that says to use list.length instead of list.sizeof:



        def new_list_sizeof : has_sizeof (list ℕ) := ⟨list.length⟩
        local attribute [instance, priority 100000] new_list_sizeof


        The goals that this produces will be easier for you to prove than those using sizeof.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 4 at 15:50

























        answered Jan 4 at 14:22









        Rob LewisRob Lewis

        51122




        51122






























            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%2f53977313%2flean-mergesort-using-increasing-well-founded-relation%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

            Mossoró

            Error while reading .h5 file using the rhdf5 package in R

            Pushsharp Apns notification error: 'InvalidToken'