feat(library/init/data/array): add Array.binSearch
This commit is contained in:
parent
2e4f5951e3
commit
dc71fafac1
7 changed files with 287 additions and 2 deletions
28
library/init/data/array/binsearch.lean
Normal file
28
library/init/data/array/binsearch.lean
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/-
|
||||
Copyright (c) 2019 Microsoft Corporation. All rights reserved.
|
||||
Released under Apache 2.0 license as described in the file LICENSE.
|
||||
Authors: Leonardo de Moura
|
||||
-/
|
||||
prelude
|
||||
import init.data.array.basic
|
||||
|
||||
namespace Array
|
||||
-- TODO: remove the [Inhabited α] parameters as soon as we have the tactic framework for automating proof generation and using Array.fget
|
||||
-- TODO: remove `partial` using well-founded recursion
|
||||
|
||||
@[specialize] partial def binSearchAux {α : Type} [Inhabited α] (lt : α → α → Bool) (as : Array α) (k : α) : Nat → Nat → Option α
|
||||
| lo hi :=
|
||||
if lo <= hi then
|
||||
let m := (lo + hi)/2 in
|
||||
let a := as.get m in
|
||||
if lt a k then binSearchAux (m+1) hi
|
||||
else if lt k a then
|
||||
if m == 0 then none
|
||||
else binSearchAux lo (m-1)
|
||||
else some a
|
||||
else none
|
||||
|
||||
@[inline] def binSearch {α : Type} [Inhabited α] (as : Array α) (k : α) (lt : α → α → Bool) (lo := 0) (hi := as.size - 1) : Option α :=
|
||||
binSearchAux lt as k lo hi
|
||||
|
||||
end Array
|
||||
|
|
@ -6,3 +6,4 @@ Authors: Gabriel Ebner
|
|||
prelude
|
||||
import init.data.array.basic
|
||||
import init.data.array.qsort
|
||||
import init.data.array.binsearch
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import init.data.array.basic
|
|||
|
||||
namespace Array
|
||||
-- TODO: remove the [Inhabited α] parameters as soon as we have the tactic framework for automating proof generation and using Array.fget
|
||||
-- TODO: remove `partial` using well-founded recursion
|
||||
|
||||
@[specialize] private partial def partitionAux {α : Type} [Inhabited α] (lt : α → α → Bool) (hi : Nat) (pivot : α) : Array α → Nat → Nat → Nat × Array α
|
||||
| as i j :=
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
add_library (stage0 OBJECT ./init/coe.cpp ./init/control/alternative.cpp ./init/control/applicative.cpp ./init/control/combinators.cpp ./init/control/conditional.cpp ./init/control/default.cpp ./init/control/estate.cpp ./init/control/except.cpp ./init/control/functor.cpp ./init/control/id.cpp ./init/control/lift.cpp ./init/control/monad.cpp ./init/control/monadfail.cpp ./init/control/option.cpp ./init/control/reader.cpp ./init/control/state.cpp ./init/core.cpp ./init/data/array/basic.cpp ./init/data/array/default.cpp ./init/data/array/qsort.cpp ./init/data/assoclist.cpp ./init/data/basic.cpp ./init/data/bytearray/basic.cpp ./init/data/bytearray/default.cpp ./init/data/char/basic.cpp ./init/data/char/default.cpp ./init/data/default.cpp ./init/data/dlist.cpp ./init/data/fin/basic.cpp ./init/data/fin/default.cpp ./init/data/hashable.cpp ./init/data/hashmap/basic.cpp ./init/data/hashmap/default.cpp ./init/data/int/basic.cpp ./init/data/int/default.cpp ./init/data/list/basic.cpp ./init/data/list/default.cpp ./init/data/list/instances.cpp ./init/data/nat/basic.cpp ./init/data/nat/bitwise.cpp ./init/data/nat/default.cpp ./init/data/nat/div.cpp ./init/data/option/basic.cpp ./init/data/option/instances.cpp ./init/data/ordering/basic.cpp ./init/data/ordering/default.cpp ./init/data/random.cpp ./init/data/rbmap/basic.cpp ./init/data/rbmap/default.cpp ./init/data/rbtree/basic.cpp ./init/data/rbtree/default.cpp ./init/data/repr.cpp ./init/data/string/basic.cpp ./init/data/string/default.cpp ./init/data/tostring.cpp ./init/data/uint.cpp ./init/default.cpp ./init/env_ext.cpp ./init/fix.cpp ./init/io.cpp ./init/lean/compiler/constfolding.cpp ./init/lean/compiler/default.cpp ./init/lean/compiler/ir/basic.cpp ./init/lean/compiler/ir/boxing.cpp ./init/lean/compiler/ir/checker.cpp ./init/lean/compiler/ir/default.cpp ./init/lean/compiler/ir/elimdead.cpp ./init/lean/compiler/ir/format.cpp ./init/lean/compiler/ir/freevars.cpp ./init/lean/compiler/ir/livevars.cpp ./init/lean/compiler/ir/normids.cpp ./init/lean/compiler/ir/pushproj.cpp ./init/lean/compiler/ir/resetreuse.cpp ./init/lean/compiler/ir/simpcase.cpp ./init/lean/compiler/util.cpp ./init/lean/config.cpp ./init/lean/declaration.cpp ./init/lean/default.cpp ./init/lean/disjoint_set.cpp ./init/lean/elaborator.cpp ./init/lean/environment.cpp ./init/lean/expander.cpp ./init/lean/expr.cpp ./init/lean/extern.cpp ./init/lean/format.cpp ./init/lean/frontend.cpp ./init/lean/kvmap.cpp ./init/lean/level.cpp ./init/lean/message.cpp ./init/lean/modifiers.cpp ./init/lean/name.cpp ./init/lean/name_mangling.cpp ./init/lean/options.cpp ./init/lean/parser/basic.cpp ./init/lean/parser/combinators.cpp ./init/lean/parser/command.cpp ./init/lean/parser/declaration.cpp ./init/lean/parser/identifier.cpp ./init/lean/parser/level.cpp ./init/lean/parser/module.cpp ./init/lean/parser/notation.cpp ./init/lean/parser/parsec.cpp ./init/lean/parser/pratt.cpp ./init/lean/parser/rec.cpp ./init/lean/parser/stringliteral.cpp ./init/lean/parser/syntax.cpp ./init/lean/parser/term.cpp ./init/lean/parser/token.cpp ./init/lean/parser/trie.cpp ./init/lean/position.cpp ./init/lean/smap.cpp ./init/lean/trace.cpp ./init/lean/util.cpp ./init/platform.cpp ./init/util.cpp ./init/wf.cpp)
|
||||
add_library (stage0 OBJECT ./init/coe.cpp ./init/control/alternative.cpp ./init/control/applicative.cpp ./init/control/combinators.cpp ./init/control/conditional.cpp ./init/control/default.cpp ./init/control/estate.cpp ./init/control/except.cpp ./init/control/functor.cpp ./init/control/id.cpp ./init/control/lift.cpp ./init/control/monad.cpp ./init/control/monadfail.cpp ./init/control/option.cpp ./init/control/reader.cpp ./init/control/state.cpp ./init/core.cpp ./init/data/array/basic.cpp ./init/data/array/binsearch.cpp ./init/data/array/default.cpp ./init/data/array/qsort.cpp ./init/data/assoclist.cpp ./init/data/basic.cpp ./init/data/bytearray/basic.cpp ./init/data/bytearray/default.cpp ./init/data/char/basic.cpp ./init/data/char/default.cpp ./init/data/default.cpp ./init/data/dlist.cpp ./init/data/fin/basic.cpp ./init/data/fin/default.cpp ./init/data/hashable.cpp ./init/data/hashmap/basic.cpp ./init/data/hashmap/default.cpp ./init/data/int/basic.cpp ./init/data/int/default.cpp ./init/data/list/basic.cpp ./init/data/list/default.cpp ./init/data/list/instances.cpp ./init/data/nat/basic.cpp ./init/data/nat/bitwise.cpp ./init/data/nat/default.cpp ./init/data/nat/div.cpp ./init/data/option/basic.cpp ./init/data/option/instances.cpp ./init/data/ordering/basic.cpp ./init/data/ordering/default.cpp ./init/data/random.cpp ./init/data/rbmap/basic.cpp ./init/data/rbmap/default.cpp ./init/data/rbtree/basic.cpp ./init/data/rbtree/default.cpp ./init/data/repr.cpp ./init/data/string/basic.cpp ./init/data/string/default.cpp ./init/data/tostring.cpp ./init/data/uint.cpp ./init/default.cpp ./init/env_ext.cpp ./init/fix.cpp ./init/io.cpp ./init/lean/compiler/constfolding.cpp ./init/lean/compiler/default.cpp ./init/lean/compiler/ir/basic.cpp ./init/lean/compiler/ir/boxing.cpp ./init/lean/compiler/ir/checker.cpp ./init/lean/compiler/ir/default.cpp ./init/lean/compiler/ir/elimdead.cpp ./init/lean/compiler/ir/format.cpp ./init/lean/compiler/ir/freevars.cpp ./init/lean/compiler/ir/livevars.cpp ./init/lean/compiler/ir/normids.cpp ./init/lean/compiler/ir/pushproj.cpp ./init/lean/compiler/ir/resetreuse.cpp ./init/lean/compiler/ir/simpcase.cpp ./init/lean/compiler/util.cpp ./init/lean/config.cpp ./init/lean/declaration.cpp ./init/lean/default.cpp ./init/lean/disjoint_set.cpp ./init/lean/elaborator.cpp ./init/lean/environment.cpp ./init/lean/expander.cpp ./init/lean/expr.cpp ./init/lean/extern.cpp ./init/lean/format.cpp ./init/lean/frontend.cpp ./init/lean/kvmap.cpp ./init/lean/level.cpp ./init/lean/message.cpp ./init/lean/modifiers.cpp ./init/lean/name.cpp ./init/lean/name_mangling.cpp ./init/lean/options.cpp ./init/lean/parser/basic.cpp ./init/lean/parser/combinators.cpp ./init/lean/parser/command.cpp ./init/lean/parser/declaration.cpp ./init/lean/parser/identifier.cpp ./init/lean/parser/level.cpp ./init/lean/parser/module.cpp ./init/lean/parser/notation.cpp ./init/lean/parser/parsec.cpp ./init/lean/parser/pratt.cpp ./init/lean/parser/rec.cpp ./init/lean/parser/stringliteral.cpp ./init/lean/parser/syntax.cpp ./init/lean/parser/term.cpp ./init/lean/parser/token.cpp ./init/lean/parser/trie.cpp ./init/lean/position.cpp ./init/lean/smap.cpp ./init/lean/trace.cpp ./init/lean/util.cpp ./init/platform.cpp ./init/util.cpp ./init/wf.cpp)
|
||||
|
|
|
|||
240
src/stage0/init/data/array/binsearch.cpp
generated
Normal file
240
src/stage0/init/data/array/binsearch.cpp
generated
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
// Lean compiler output
|
||||
// Module: init.data.array.binsearch
|
||||
// Imports: init.data.array.basic
|
||||
#include "runtime/object.h"
|
||||
#include "runtime/apply.h"
|
||||
typedef lean::object obj; typedef lean::usize usize;
|
||||
typedef lean::uint8 uint8; typedef lean::uint16 uint16;
|
||||
typedef lean::uint32 uint32; typedef lean::uint64 uint64;
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
#pragma clang diagnostic ignored "-Wunused-label"
|
||||
#elif defined(__GNUC__) && !defined(__CLANG__)
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#pragma GCC diagnostic ignored "-Wunused-label"
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#endif
|
||||
obj* l_Array_binSearch___rarg(obj*, obj*, obj*, obj*, obj*, obj*);
|
||||
namespace lean {
|
||||
obj* nat_sub(obj*, obj*);
|
||||
}
|
||||
obj* l_Array_binSearchAux___boxed(obj*);
|
||||
obj* l_Array_binSearchAux___rarg___boxed(obj*, obj*, obj*, obj*, obj*, obj*);
|
||||
obj* l_Array_binSearch___rarg___boxed(obj*, obj*, obj*, obj*, obj*, obj*);
|
||||
obj* l_Array_binSearch___boxed(obj*);
|
||||
obj* l_Array_binSearch(obj*);
|
||||
obj* l_Array_binSearchAux___main___rarg___boxed(obj*, obj*, obj*, obj*, obj*, obj*);
|
||||
namespace lean {
|
||||
obj* nat_add(obj*, obj*);
|
||||
}
|
||||
namespace lean {
|
||||
uint8 nat_dec_eq(obj*, obj*);
|
||||
}
|
||||
obj* l_Array_binSearchAux___main___rarg(obj*, obj*, obj*, obj*, obj*, obj*);
|
||||
obj* l_Array_binSearchAux(obj*);
|
||||
obj* l_Array_binSearchAux___main___boxed(obj*);
|
||||
namespace lean {
|
||||
uint8 nat_dec_le(obj*, obj*);
|
||||
}
|
||||
namespace lean {
|
||||
obj* nat_div(obj*, obj*);
|
||||
}
|
||||
obj* l_Array_binSearchAux___main(obj*);
|
||||
obj* l_Array_binSearchAux___rarg(obj*, obj*, obj*, obj*, obj*, obj*);
|
||||
obj* l_Array_binSearchAux___main___rarg(obj* x_0, obj* x_1, obj* x_2, obj* x_3, obj* x_4, obj* x_5) {
|
||||
_start:
|
||||
{
|
||||
uint8 x_6;
|
||||
x_6 = lean::nat_dec_le(x_4, x_5);
|
||||
if (x_6 == 0)
|
||||
{
|
||||
obj* x_12;
|
||||
lean::dec(x_5);
|
||||
lean::dec(x_4);
|
||||
lean::dec(x_1);
|
||||
lean::dec(x_3);
|
||||
lean::dec(x_0);
|
||||
x_12 = lean::box(0);
|
||||
return x_12;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj* x_13; obj* x_14; obj* x_15; obj* x_18; obj* x_22; uint8 x_23;
|
||||
x_13 = lean::nat_add(x_4, x_5);
|
||||
x_14 = lean::mk_nat_obj(2ul);
|
||||
x_15 = lean::nat_div(x_13, x_14);
|
||||
lean::dec(x_13);
|
||||
lean::inc(x_0);
|
||||
x_18 = lean::array_get(x_0, x_2, x_15);
|
||||
lean::inc(x_3);
|
||||
lean::inc(x_18);
|
||||
lean::inc(x_1);
|
||||
x_22 = lean::apply_2(x_1, x_18, x_3);
|
||||
x_23 = lean::unbox(x_22);
|
||||
if (x_23 == 0)
|
||||
{
|
||||
obj* x_28; uint8 x_29;
|
||||
lean::dec(x_5);
|
||||
lean::inc(x_18);
|
||||
lean::inc(x_3);
|
||||
lean::inc(x_1);
|
||||
x_28 = lean::apply_2(x_1, x_3, x_18);
|
||||
x_29 = lean::unbox(x_28);
|
||||
if (x_29 == 0)
|
||||
{
|
||||
obj* x_35;
|
||||
lean::dec(x_15);
|
||||
lean::dec(x_4);
|
||||
lean::dec(x_1);
|
||||
lean::dec(x_3);
|
||||
lean::dec(x_0);
|
||||
x_35 = lean::alloc_cnstr(1, 1, 0);
|
||||
lean::cnstr_set(x_35, 0, x_18);
|
||||
return x_35;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj* x_37; uint8 x_38;
|
||||
lean::dec(x_18);
|
||||
x_37 = lean::mk_nat_obj(0ul);
|
||||
x_38 = lean::nat_dec_eq(x_15, x_37);
|
||||
if (x_38 == 0)
|
||||
{
|
||||
obj* x_39; obj* x_40;
|
||||
x_39 = lean::mk_nat_obj(1ul);
|
||||
x_40 = lean::nat_sub(x_15, x_39);
|
||||
lean::dec(x_15);
|
||||
x_5 = x_40;
|
||||
goto _start;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj* x_48;
|
||||
lean::dec(x_15);
|
||||
lean::dec(x_4);
|
||||
lean::dec(x_1);
|
||||
lean::dec(x_3);
|
||||
lean::dec(x_0);
|
||||
x_48 = lean::box(0);
|
||||
return x_48;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obj* x_51; obj* x_52;
|
||||
lean::dec(x_18);
|
||||
lean::dec(x_4);
|
||||
x_51 = lean::mk_nat_obj(1ul);
|
||||
x_52 = lean::nat_add(x_15, x_51);
|
||||
lean::dec(x_15);
|
||||
x_4 = x_52;
|
||||
goto _start;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
obj* l_Array_binSearchAux___main(obj* x_0) {
|
||||
_start:
|
||||
{
|
||||
obj* x_1;
|
||||
x_1 = lean::alloc_closure(reinterpret_cast<void*>(l_Array_binSearchAux___main___rarg___boxed), 6, 0);
|
||||
return x_1;
|
||||
}
|
||||
}
|
||||
obj* l_Array_binSearchAux___main___rarg___boxed(obj* x_0, obj* x_1, obj* x_2, obj* x_3, obj* x_4, obj* x_5) {
|
||||
_start:
|
||||
{
|
||||
obj* x_6;
|
||||
x_6 = l_Array_binSearchAux___main___rarg(x_0, x_1, x_2, x_3, x_4, x_5);
|
||||
lean::dec(x_2);
|
||||
return x_6;
|
||||
}
|
||||
}
|
||||
obj* l_Array_binSearchAux___main___boxed(obj* x_0) {
|
||||
_start:
|
||||
{
|
||||
obj* x_1;
|
||||
x_1 = l_Array_binSearchAux___main(x_0);
|
||||
lean::dec(x_0);
|
||||
return x_1;
|
||||
}
|
||||
}
|
||||
obj* l_Array_binSearchAux___rarg(obj* x_0, obj* x_1, obj* x_2, obj* x_3, obj* x_4, obj* x_5) {
|
||||
_start:
|
||||
{
|
||||
obj* x_6;
|
||||
x_6 = l_Array_binSearchAux___main___rarg(x_0, x_1, x_2, x_3, x_4, x_5);
|
||||
return x_6;
|
||||
}
|
||||
}
|
||||
obj* l_Array_binSearchAux(obj* x_0) {
|
||||
_start:
|
||||
{
|
||||
obj* x_1;
|
||||
x_1 = lean::alloc_closure(reinterpret_cast<void*>(l_Array_binSearchAux___rarg___boxed), 6, 0);
|
||||
return x_1;
|
||||
}
|
||||
}
|
||||
obj* l_Array_binSearchAux___rarg___boxed(obj* x_0, obj* x_1, obj* x_2, obj* x_3, obj* x_4, obj* x_5) {
|
||||
_start:
|
||||
{
|
||||
obj* x_6;
|
||||
x_6 = l_Array_binSearchAux___rarg(x_0, x_1, x_2, x_3, x_4, x_5);
|
||||
lean::dec(x_2);
|
||||
return x_6;
|
||||
}
|
||||
}
|
||||
obj* l_Array_binSearchAux___boxed(obj* x_0) {
|
||||
_start:
|
||||
{
|
||||
obj* x_1;
|
||||
x_1 = l_Array_binSearchAux(x_0);
|
||||
lean::dec(x_0);
|
||||
return x_1;
|
||||
}
|
||||
}
|
||||
obj* l_Array_binSearch___rarg(obj* x_0, obj* x_1, obj* x_2, obj* x_3, obj* x_4, obj* x_5) {
|
||||
_start:
|
||||
{
|
||||
obj* x_6;
|
||||
x_6 = l_Array_binSearchAux___main___rarg(x_0, x_3, x_1, x_2, x_4, x_5);
|
||||
return x_6;
|
||||
}
|
||||
}
|
||||
obj* l_Array_binSearch(obj* x_0) {
|
||||
_start:
|
||||
{
|
||||
obj* x_1;
|
||||
x_1 = lean::alloc_closure(reinterpret_cast<void*>(l_Array_binSearch___rarg___boxed), 6, 0);
|
||||
return x_1;
|
||||
}
|
||||
}
|
||||
obj* l_Array_binSearch___rarg___boxed(obj* x_0, obj* x_1, obj* x_2, obj* x_3, obj* x_4, obj* x_5) {
|
||||
_start:
|
||||
{
|
||||
obj* x_6;
|
||||
x_6 = l_Array_binSearch___rarg(x_0, x_1, x_2, x_3, x_4, x_5);
|
||||
lean::dec(x_1);
|
||||
return x_6;
|
||||
}
|
||||
}
|
||||
obj* l_Array_binSearch___boxed(obj* x_0) {
|
||||
_start:
|
||||
{
|
||||
obj* x_1;
|
||||
x_1 = l_Array_binSearch(x_0);
|
||||
lean::dec(x_0);
|
||||
return x_1;
|
||||
}
|
||||
}
|
||||
obj* initialize_init_data_array_basic(obj*);
|
||||
static bool _G_initialized = false;
|
||||
obj* initialize_init_data_array_binsearch(obj* w) {
|
||||
if (_G_initialized) return w;
|
||||
_G_initialized = true;
|
||||
if (io_result_is_error(w)) return w;
|
||||
w = initialize_init_data_array_basic(w);
|
||||
if (io_result_is_error(w)) return w;
|
||||
return w;
|
||||
}
|
||||
5
src/stage0/init/data/array/default.cpp
generated
5
src/stage0/init/data/array/default.cpp
generated
|
|
@ -1,6 +1,6 @@
|
|||
// Lean compiler output
|
||||
// Module: init.data.array.default
|
||||
// Imports: init.data.array.basic init.data.array.qsort
|
||||
// Imports: init.data.array.basic init.data.array.qsort init.data.array.binsearch
|
||||
#include "runtime/object.h"
|
||||
#include "runtime/apply.h"
|
||||
typedef lean::object obj; typedef lean::usize usize;
|
||||
|
|
@ -16,6 +16,7 @@ typedef lean::uint32 uint32; typedef lean::uint64 uint64;
|
|||
#endif
|
||||
obj* initialize_init_data_array_basic(obj*);
|
||||
obj* initialize_init_data_array_qsort(obj*);
|
||||
obj* initialize_init_data_array_binsearch(obj*);
|
||||
static bool _G_initialized = false;
|
||||
obj* initialize_init_data_array_default(obj* w) {
|
||||
if (_G_initialized) return w;
|
||||
|
|
@ -25,5 +26,7 @@ w = initialize_init_data_array_basic(w);
|
|||
if (io_result_is_error(w)) return w;
|
||||
w = initialize_init_data_array_qsort(w);
|
||||
if (io_result_is_error(w)) return w;
|
||||
w = initialize_init_data_array_binsearch(w);
|
||||
if (io_result_is_error(w)) return w;
|
||||
return w;
|
||||
}
|
||||
|
|
|
|||
12
tests/playground/binsearch.lean
Normal file
12
tests/playground/binsearch.lean
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
def mkAssocArray : Nat → Array (Nat × Bool) → Array (Nat × Bool)
|
||||
| 0 as := as
|
||||
| (i+1) as := mkAssocArray i (as.push (i, i % 2 == 0))
|
||||
|
||||
def main (xs : List String) : IO Unit :=
|
||||
do
|
||||
let n := xs.head.toNat,
|
||||
let as := mkAssocArray n Array.empty,
|
||||
let as := as.qsort (λ a b, a.1 < b.1),
|
||||
(2*n).mfor $ λ i, do
|
||||
let entry := as.binSearch (i, false) (λ a b, a.1 < b.1),
|
||||
IO.println (">> " ++ toString i ++ " ==> " ++ toString entry)
|
||||
Loading…
Add table
Reference in a new issue