我正在尝试在精益中创建mergesort定义,并创建了以下代码:
{% extends "admin/change_list.html" %}
{% load staticfiles %}
{% block content %}
<div align="right">
<form id="generate-form" method="POST">
{% csrf_token %}
<select>
<option value="">-- section name --</option>
{% for section in sections %}
<option value="{{ section.short_name }}">{{ section.name }}</option>
{% endfor %}
</select>
<input type="text" name="from_date" class="vTextField" placeholder="from">
<input type="text" name="to_date" class="vTextField" placeholder="to">
<input type="submit" value="Generate" class="default" id="gen-schedules"
style="margin:0; height: 30px; padding-top: 5px;">
<form>
</div>
{{ block.super }}
{% endblock %}
具有合并定义
def mergesort (a: ℕ): list ℕ → list ℕ
| [] := []
| [a] := [a]
| (x::xs) := merge (mergesort (fhalf xs)) (mergesort (sndhalf xs))
以及半/ sndhalf定义:
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)
但是,我收到以下错误消息:
无法证明递归应用程序在减少,有充分的依据 关系
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
可能的解决方案:
在定义末尾使用
@has_well_founded.r (list ℕ) (@has_well_founded_of_has_sizeof (list ℕ) (@list.has_sizeof ℕ nat.has_sizeof))
关键字来指定用于建立良好关系并减少证明的策略。默认的递减策略使用“假设”策略,因此可以使用“ have”表达式提供提示(即本地证明)。嵌套异常包含递减策略的失败状态。
有人可以帮助我证明合并排序正在减少吗?
答案 0 :(得分:4)
首先,请注意mergesort
的定义存在多个问题。第一,参数a
是不必要的,永远不会使用。 (第二行中匹配的a
是新鲜的。)二,在x::xs
情况下,您完全忘记了x
。要查看函数的实际作用,可以像在meta
中一样添加关键字meta def mergesort
。这将禁用终止检查,因此您可以#eval mergesort 2 [1, 3, 2]
并看到没有得到想要的东西。在您撰写本文时,我将继续回答。
有一个默认的有根据的关系,证明它的默认方法是在本地上下文中查找证明。通过查看定义中的错误消息,您可以看到Lean期望得到的证明:它需要list.sizeof (fhalf xs) < x + (1 + list.sizeof xs)
和list.sizeof (sndhalf xs) < x + (1 + list.sizeof xs)
的证明。因此,通过添加行
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))
此策略将成功。您需要填写这些sorry
。
使用linarith
中可用的mathlib
策略(通过import tactic.linarith
),您可以跳过一些算法:
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))
因此,用证明替换那些sorry
,您很高兴。您可能想证明类似
lemma sizeof_take_le {α} [h : has_sizeof α] : ∀ n (xs : list α),
list.sizeof (list.take n xs) ≤ list.sizeof xs
更正mergesort
的定义后,详细信息将有所更改。
另一种方法是更改建立良好的关系和决策策略,就像mathlib
定义中所做的那样:https://github.com/leanprover/mathlib/blob/master/data/list/sort.lean#L174
不幸的是,执行此操作的界面相当底层,我不知道它是否记录在何处。
要在不使用using_well_founded
的情况下更改关系,可以添加一个使用list.length
而不是list.sizeof
的本地实例:
def new_list_sizeof : has_sizeof (list ℕ) := ⟨list.length⟩
local attribute [instance, priority 100000] new_list_sizeof
由此产生的目标比使用sizeof
的目标更容易证明。