See Section "Other goodies" at https://github.com/leanprover/lean/wiki/Refactoring-structures This commit also improves the support for projections in the unifier/matcher. Now, we consider the extra case-split for projections. Given a projection `proj`, and the constraint `proj s =?= proj t`, we need to try first `s =?= t` and if it fails, then try to reduce. This is needed in the standard library because we now have constraints such as: ``` @has_le.le ?A ?s ?a ?b =?= @has_le.le nat nat.has_add x y ``` If we reduce the right hand side, we get the unsolvable constraint ``` @has_le.le ?A ?s ?a ?b =?= nat.le x y ``` Before this change, the constraint was `@le ?A ?s ?a ?b =?= @le nat nat.has_add x y`, and we already perform a case-split in this case. Moreover, projections were eagerly reduced whenever possible. The extra case-split generates a performance problem in several tests. For example `fib 8 = 34` was timing out. I worked around this issue by performing the case-split only when the constraint contains meta-variables. There are also minor issues. Example. `<` is notation for `has_lt.lt`, but `>` is for `gt`.
35 lines
1.1 KiB
Text
35 lines
1.1 KiB
Text
/-
|
|
Copyright (c) 2016 Microsoft Corporation. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
Authors: Leonardo de Moura
|
|
-/
|
|
prelude
|
|
import init.wf init.data.nat.basic
|
|
namespace nat
|
|
|
|
private def div_rec_lemma {x y : nat} : 0 < y ∧ y ≤ x → x - y < x :=
|
|
λ h, and.rec (λ ypos ylex, sub_lt (nat.lt_of_lt_of_le ypos ylex) ypos) h
|
|
|
|
private def div.F (x : nat) (f : Π x₁, x₁ < x → nat → nat) (y : nat) : nat :=
|
|
if h : 0 < y ∧ y ≤ x then f (x - y) (div_rec_lemma h) y + 1 else zero
|
|
|
|
protected def div := well_founded.fix lt_wf div.F
|
|
|
|
instance : has_div nat :=
|
|
⟨nat.div⟩
|
|
|
|
lemma div_def_aux (x y : nat) : x / y = if h : 0 < y ∧ y ≤ x then (x - y) / y + 1 else 0 :=
|
|
congr_fun (well_founded.fix_eq lt_wf div.F x) y
|
|
|
|
private def mod.F (x : nat) (f : Π x₁, x₁ < x → nat → nat) (y : nat) : nat :=
|
|
if h : 0 < y ∧ y ≤ x then f (x - y) (div_rec_lemma h) y else x
|
|
|
|
protected def mod := well_founded.fix lt_wf mod.F
|
|
|
|
instance : has_mod nat :=
|
|
⟨nat.mod⟩
|
|
|
|
lemma mod_def_aux (x y : nat) : x % y = if h : 0 < y ∧ y ≤ x then (x - y) % y else x :=
|
|
congr_fun (well_founded.fix_eq lt_wf mod.F x) y
|
|
|
|
end nat
|