~/bend-docscommunity

util.bend checks

raw source on the hub · import 0xa2f9d6ef8c474468bf1de15ebe70c512/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_sum source · line 104 · raw

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

Sum of a Nat histogram. Used to lock mid-split count conservation.

def bit source · line 113 · raw

@b:Bool -> Nat

1 when i is a valid bin of a length-n histogram, else 0. List.set (and therefore inc_at) is a no-op at i >= n.

def bin_hit source · line 120 · raw

@+i:Nat -> @+n:Nat -> Nat

def nats_add source · line 123 · raw

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

def vec_min source · line 134 · raw

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

def vec_max source · line 145 · raw

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

def vec_sub source · line 156 · raw

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

def vec_scale source · line 167 · raw

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

def vec_dot source · line 174 · raw

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

def vec_sqnorm source · line 185 · raw

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

def ones_f32 source · line 188 · raw

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

def zeros_f32 source · line 191 · raw

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

def get_f32 source · line 194 · raw

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

def set_f32 source · line 197 · raw

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

def f32_or_one source · line 200 · raw

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

def denom source · line 208 · 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 212 · raw

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

def csv_step source · line 223 · raw

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

def show_f32s source · line 230 · raw

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

def f32s_eq source · line 233 · raw

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

def has_f32s source · line 244 · raw

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

def g12_scale source · line 258 · raw

F32

Decision-variable duplicate key: 12 decimal places, round(x*1e12)/1e12. C# DecisionKey is double.ToString("G12") (12 significant digits). Those are not the same format. Near magnitude 1, F32 ULP is coarser than 1e-12, so 12-dp rounding often does nothing. Below about 1e-5 a 12-dp bin is wider than the F32 ULP and the round changes the value (1.234567e-8 → 1.2346e-8). This tree keeps 12-dp keys. It does not match C# G12. See src/g12_key.bend.

def g12_round_abs source · line 261 · raw

@+x:F32 -> F32

def g12_one.signed source · line 265 · raw

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

def g12_one source · line 272 · raw

@+x:F32 -> F32

def g12_vec.go source · line 336 · 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 343 · raw

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

Templates

template map_halves.go source · line 278 · 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 302 · 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 307 · 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 330 · raw

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