~/bend-docscommunity

util.bend checks

raw source on the hub · import 0xcd07e24a626a62e74603d48f436cd679/util.bend as Util

Shared helpers. Parallelize independent list splits; keep these total. Population maps use mid-split + a b = f(lo) f(hi) (bend guide Parallelism). Fuel is |xs| so the Nat shrinks; halves stay observationally ordered.

1 import
import Base

Definitions

def list_len source · line 7 · raw

@-A:Data -> @xs:List<&2, A> -> Nat

def list_take_pad source · line 12 · raw

@-A:Data -> @+fill:A -> @xs:List<&2, A> -> @+n:Nat -> List<&2, A>

|take(xs ++ replicate(n, fill), n)| = n. Identity when |xs| = n (take never reads the pad). Used to lock Run / select to the law size.

def word_all_false source · line 17 · raw

@n:Nat -> @w:Word(n) -> Bool

IEEE +0.0 is the all-false Word(32). Definitional on the 0.0 literal, so p=0 operator laws skip F32.is_gt / F32.is_eq (opaque Base laws).

def f32_is_zero source · line 28 · raw

@x:F32 -> Bool

def nat_min.fin source · line 33 · raw

@+a:Nat -> @+b:Nat -> @c:Bool -> Nat

def nat_min source · line 40 · raw

@+a:Nat -> @+b:Nat -> Nat

def nat_max.fin source · line 43 · raw

@+a:Nat -> @+b:Nat -> @c:Bool -> Nat

def nat_max source · line 50 · raw

@+a:Nat -> @+b:Nat -> Nat

def nat_pow source · line 53 · raw

@+b:Nat -> @e:Nat -> Nat

def binomial source · line 61 · raw

@+n:Nat -> @+k:Nat -> Nat

C(n, k). Das–Dennis count = C(p + M - 1, M - 1).

def in_nats source · line 70 · raw

@+x:Nat -> @xs:List<&2, Nat> -> Bool

def keep_if source · line 73 · raw

@-A:Data -> @+h:A -> @rest:List<&2, A> -> @keep:Bool -> List<&2, A>

def minus.put source · line 80 · raw

@h:Nat -> @rest:List<&2, Nat> -> @drop:Bool -> List<&2, Nat>

def minus source · line 87 · raw

@+xs:List<&2, Nat> -> @+ys:List<&2, Nat> -> List<&2, Nat>

def get_nat source · line 94 · raw

@xs:List<&2, Nat> -> @i:Nat -> Nat

def inc_at source · line 97 · raw

@+xs:List<&2, Nat> -> @+i:Nat -> List<&2, Nat>

def zeros_nat source · line 100 · raw

@n:Nat -> List<&2, Nat>

def nats_add source · line 103 · raw

@a:List<&2, Nat> -> @b:List<&2, Nat> -> List<&2, Nat>

def vec_min source · line 114 · raw

@a:List<&2, F32> -> @b:List<&2, F32> -> List<&2, F32>

def vec_max source · line 125 · raw

@a:List<&2, F32> -> @b:List<&2, F32> -> List<&2, F32>

def vec_sub source · line 136 · raw

@a:List<&2, F32> -> @b:List<&2, F32> -> List<&2, F32>

def vec_scale source · line 147 · raw

@+s:F32 -> @v:List<&2, F32> -> List<&2, F32>

def vec_dot source · line 154 · raw

@a:List<&2, F32> -> @b:List<&2, F32> -> F32

def vec_sqnorm source · line 165 · raw

@+v:List<&2, F32> -> F32

def ones_f32 source · line 168 · raw

@n:Nat -> List<&2, F32>

def zeros_f32 source · line 171 · raw

@n:Nat -> List<&2, F32>

def get_f32 source · line 174 · raw

@xs:List<&2, F32> -> @i:Nat -> F32

def set_f32 source · line 177 · raw

@xs:List<&2, F32> -> @i:Nat -> @x:F32 -> List<&2, F32>

def f32_or_one source · line 180 · raw

@+span:F32 -> @tiny:Bool -> F32

def denom source · line 188 · raw

@+lo:F32 -> @+hi:F32 -> F32

C# Normalize: denom < 1e-12 → 1.0 (intercept span uses the same floor).

def vec_norm_div source · line 192 · raw

@f:List<&2, F32> -> @ideal:List<&2, F32> -> @nadir:List<&2, F32> -> List<&2, F32>

def csv_step source · line 203 · raw

@x:F32 -> @acc:String -> String

def show_f32s source · line 210 · raw

@xs:List<&2, F32> -> String

def f32s_eq source · line 213 · raw

@a:List<&2, F32> -> @b:List<&2, F32> -> Bool

def has_f32s source · line 224 · raw

@+needle:List<&2, F32> -> @xs:List<&2, List<&2, F32>> -> Bool

def g12_scale source · line 235 · raw

F32

C# Unsga3Algorithm.DecisionKey: double.ToString("G12") — 12 significant digits, which on the unit box is 12 decimal places. Round each coord to 12 dp before duplicate-key compare. Bend F32 ULP is coarser than 1e-12, so this matches C# G12 at the precision this tree has.

def g12_round_abs source · line 238 · raw

@+x:F32 -> F32

def g12_one.signed source · line 242 · raw

@+x:F32 -> @neg:Bool -> F32

def g12_one source · line 249 · raw

@+x:F32 -> F32

def g12_vec.go source · line 313 · raw

@xs:List<&2, F32> -> @acc:List<&2, F32> -> List<&2, F32>

Sequential cons walk (guide: the list is the shape a flat loop walks). n_var is 12–30 on the oracles; mid-split take/drop of that spine is more expensive than a tail walk. Same rounding as the old map_halves.

def g12_vec source · line 320 · raw

@xs:List<&2, F32> -> List<&2, F32>

Templates

template map_halves.go source · line 255 · raw

@-A:Data -> @-B:Data -> @-C:Data -> @-f:(@+c:C -> @+x:A -> B) -> @+ctx:C -> @+fuel:Nat -> @xs:List<&2, A> -> List<&2, B>

Balanced fork-join map. Singleton / empty stay sequential. Fuel 0 is a total fallback (public callers pass |xs|). ~f is a closed top-level. Mid take/drop is inlined: a computed pair cannot be matched.

template map_halves source · line 279 · raw

@-A:Data -> @-B:Data -> @-C:Data -> @-f:(@+c:C -> @+x:A -> B) -> @+ctx:C -> @+xs:List<&2, A> -> List<&2, B>

template filter_halves.go source · line 284 · raw

@-A:Data -> @-C:Data -> @-p:(@+c:C -> @+x:A -> Bool) -> @+ctx:C -> @+fuel:Nat -> @xs:List<&2, A> -> List<&2, A>

Independent keep/drop. Mid-split; take ++ drop matches the old tail-first cons_if walk (original relative order).

template filter_halves source · line 307 · raw

@-A:Data -> @-C:Data -> @-p:(@+c:C -> @+x:A -> Bool) -> @+ctx:C -> @+xs:List<&2, A> -> List<&2, A>