randomizable squeeze
This commit is contained in:
parent
60cefa158b
commit
3ab5c87a76
@ -83,7 +83,7 @@ B add_c1(B t, B x) {
|
||||
}
|
||||
B sub_c2(B,B,B);
|
||||
#define SUB_BODY(FEXPR) return sub_c2(t, m_f64(0), x);
|
||||
#define NOT_BODY(FEXPR) x = squeeze_numTry(x, &xe); return xe==el_bit? bit_negate(x) : C2(sub, m_f64(1), x);
|
||||
#define NOT_BODY(FEXPR) x = squeeze_numTry(x, &xe, SQ_ANY); return xe==el_bit? bit_negate(x) : C2(sub, m_f64(1), x);
|
||||
|
||||
GC1i("-", sub, -v, el_bit, bit_sel(x,m_f64(0),m_f64(-1)), SUB_BODY)
|
||||
GC1i("|", stile, fabs(v), el_bit, x, STILE_BODY)
|
||||
|
||||
@ -730,7 +730,7 @@ NOINLINE B for_cells_SA(B f, B w, B x, ur xcr, ur xr, u32 chr) { // w⊸F⎉xcr
|
||||
if (isArr(w) && xcr==1) {
|
||||
if (!TI(w,arrD1)) {
|
||||
u8 xe;
|
||||
w = squeeze_numTry(w, &xe);
|
||||
w = squeeze_numTry(w, &xe, SQ_ANY);
|
||||
if (xe==el_B) break;
|
||||
}
|
||||
assert(xr > 1);
|
||||
|
||||
@ -280,7 +280,7 @@ B group_c2(B t, B w, B x) {
|
||||
ur xr = RNK(x);
|
||||
if (isArr(w) && RNK(w)==1 && xr>=1) {
|
||||
u8 we = TI(w,elType);
|
||||
if (!elInt(we)) w = squeeze_numTry(w, &we);
|
||||
if (!elInt(we)) w = squeeze_numTry(w, &we, SQ_ANY);
|
||||
if (elInt(we)) {
|
||||
usz wia = IA(w);
|
||||
usz* xsh = SH(x);
|
||||
|
||||
@ -337,7 +337,7 @@ B scan_c1(Md1D* d, B x) { B f = d->f;
|
||||
if (xe==el_i32) { i32* xp=i32any_ptr(x); for (usz i=1; i<ia; i++) { c = c!=xp[i]; bitp_set(rp,i,c); } decG(x); return r; }
|
||||
UD;
|
||||
}
|
||||
if (rtid==n_or) { x=squeeze_numTry(x, &xe); if (xe==el_bit) return scan_or(x, ia); }
|
||||
if (rtid==n_or) { x=squeeze_numTry(x, &xe, SQ_ANY); if (xe==el_bit) return scan_or(x, ia); }
|
||||
}
|
||||
base:;
|
||||
if (ia!=n && ia >= 6 * (u64)n && isPervasiveDy(f)) return scan_arith(f, m_f64(0), x, SH(x));
|
||||
|
||||
@ -230,7 +230,7 @@ B select_c2(B t, B w, B x) {
|
||||
decG(w);
|
||||
u8 w0e = TI(w0,elType);
|
||||
if (elNum(w0e)) return C2(select, w0, x);
|
||||
w0 = squeeze_numTry(w0, &w0e);
|
||||
w0 = squeeze_numTry(w0, &w0e, SQ_MSGREQ(SQ_NUM));
|
||||
if (elNum(w0e)) return C2(select, w0, x);
|
||||
w = m_vec1(w0);
|
||||
}
|
||||
@ -372,7 +372,7 @@ B select_c2(B t, B w, B x) {
|
||||
// else fallthrough - want to do integer 𝕨 if possible
|
||||
}
|
||||
case el_B: case el_c8: case el_c16: case el_c32: {
|
||||
w = squeeze_numTry(w, &we);
|
||||
w = squeeze_numTry(w, &we, SQ_MSGREQ(SQ_NUM));
|
||||
if (RANDOMIZE_HEURISTICS && we==el_f64) goto generic_l; // avoid infinite loop
|
||||
if (elNum(we)) goto retry;
|
||||
goto def_xf_base;
|
||||
@ -952,7 +952,7 @@ B select_rows_B(B x, ux csz, ux cam, B inds) { // consumes inds,x; ⥊ inds⊸
|
||||
}
|
||||
u8 ie = TI(inds,elType);
|
||||
if (csz<=2? ie!=el_bit : csz<=128? ie>el_i8 : !elInt(ie)) {
|
||||
inds = squeeze_numTry(inds, &ie);
|
||||
inds = squeeze_numTry(inds, &ie, SQ_BEST);
|
||||
if (!elInt(ie)) goto generic;
|
||||
}
|
||||
void* ip = tyany_ptr(inds);
|
||||
@ -1023,7 +1023,7 @@ B select_ucw(B t, B o, B w, B x) {
|
||||
} else {
|
||||
we = TI(w,elType);
|
||||
if (!elInt(we)) {
|
||||
w = squeeze_numTry(w, &we);
|
||||
w = squeeze_numTry(w, &we, SQ_MSGREQ(SQ_NUM));
|
||||
if (!elNum(we)) goto def;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1207,7 +1207,7 @@ NOINLINE B rotate_highrank(bool inv, B w, B x) {
|
||||
if (wia==0) { r=x; goto decW_ret; }
|
||||
u8 we = TI(w,elType);
|
||||
if (!elNum(we)) {
|
||||
w = squeeze_numTry(w, &we);
|
||||
w = squeeze_numTry(w, &we, SQ_NUM);
|
||||
if (!elNum(we)) thrF("𝕨⌽%U𝕩: 𝕨 contained non-number", INV);
|
||||
}
|
||||
bool origF64 = we==el_f64;
|
||||
|
||||
@ -577,7 +577,7 @@ B slash_c1(B t, B x) {
|
||||
usz xia = IA(x);
|
||||
B r;
|
||||
u8 xe = TI(x,elType);
|
||||
if (xe!=el_bit && s<=xia) x = squeeze_numTry(x, &xe);
|
||||
if (xe!=el_bit && s<=xia) x = squeeze_numTry(x, &xe, SQ_NUM);
|
||||
if (xe==el_bit) {
|
||||
r = where(x, xia, s);
|
||||
} else if (RARE(xia > (usz)I32_MAX+1)) {
|
||||
@ -630,7 +630,7 @@ B slash_c2(B t, B w, B x) {
|
||||
if (isArr(w)) {
|
||||
we = TI(w,elType);
|
||||
if (!elInt(we)) {
|
||||
w = squeeze_numTry(w, &we);
|
||||
w = squeeze_numTry(w, &we, SQ_MSGREQ(SQ_NUM));
|
||||
if (!elNum(we)) goto base;
|
||||
}
|
||||
ur wr = RNK(w);
|
||||
@ -670,7 +670,7 @@ B slash_c2(B t, B w, B x) {
|
||||
if (xl>6 || (xl<3 && xl!=0)) goto arrW_base;
|
||||
if (s<=wia) {
|
||||
if (s==0) { r = zeroCells(x); goto decWX_ret; }
|
||||
w = squeeze_numTry(w, &we);
|
||||
w = squeeze_numTry(w, &we, SQ_NUM);
|
||||
if (we==el_bit) goto wbool;
|
||||
}
|
||||
// s≠0 now
|
||||
@ -1021,7 +1021,7 @@ B slash_im(B t, B x) {
|
||||
break;
|
||||
}
|
||||
case el_c8: case el_c16: case el_c32: case el_B: {
|
||||
x = squeeze_numTry(x, &xe);
|
||||
x = squeeze_numTry(x, &xe, SQ_NUM);
|
||||
if (elNum(xe)) goto retry;
|
||||
B* xp = TO_BPTR(x);
|
||||
for (usz i=0; i<xia; i++) o2i64(xp[i]);
|
||||
@ -1069,7 +1069,7 @@ B slash_ucw(B t, B o, B w, B x) {
|
||||
usz ia = IA(x);
|
||||
u8 we = TI(w,elType);
|
||||
if (we != el_bit) {
|
||||
w = squeeze_numTry(w, &we);
|
||||
w = squeeze_numTry(w, &we, SQ_NUM);
|
||||
if (we != el_bit) {
|
||||
if (!elNum(we)) goto base;
|
||||
i64 bounds[2];
|
||||
|
||||
@ -121,7 +121,7 @@ B parseFloat_c1(B t, B x) {
|
||||
if (isAtm(x)) thrM("•ParseFloat 𝕩: Expected a character list argument");
|
||||
if (TI(x,elType)!=el_c8) {
|
||||
u8 xe;
|
||||
x = squeeze_chrTry(x, &xe);
|
||||
x = squeeze_chrTry(x, &xe, SQ_BEST);
|
||||
if (xe!=el_c8) {
|
||||
if (IA(x)==0) goto empty;
|
||||
if (elChr(xe)) malformed: thrM("•ParseFloat 𝕩: Malformed input");
|
||||
|
||||
@ -131,10 +131,10 @@ B withFill(B x, B fill) { // consumes both
|
||||
if (!FL_HAS(x,fl_squoze)) {
|
||||
u8 xe;
|
||||
if (isNum(fill)) {
|
||||
x = squeeze_numTry(x, &xe);
|
||||
x = squeeze_numTry(x, &xe, SQ_ANY);
|
||||
if (elNum(xe)) return x;
|
||||
} else if (isC32(fill)) {
|
||||
x = squeeze_chrTry(x, &xe);
|
||||
x = squeeze_chrTry(x, &xe, SQ_ANY);
|
||||
if (elChr(xe)) return x;
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,10 +630,46 @@ DEBUG_FN void g_pst(void) { vm_pstLive(); fflush(stdout); fflush(stderr); }
|
||||
|
||||
#if RANDOMIZE_HEURISTICS
|
||||
#include "../utils/wyhash.h"
|
||||
#ifndef MATCH_ERROR_MESSAGES
|
||||
#define MATCH_ERROR_MESSAGES 1
|
||||
#endif
|
||||
|
||||
u64 seed;
|
||||
bool heuristic_rand(bool heuristic, bool true_req, bool false_req) {
|
||||
assert(heuristic? true_req : false_req);
|
||||
if (!true_req | !false_req) return heuristic;
|
||||
return wyrand(&seed) & 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SqRes squeeze_numTryImpl(B x);
|
||||
SqRes squeeze_chrTryImpl(B x);
|
||||
|
||||
static u32 squeeze_processReq(u32 req) {
|
||||
if (MATCH_ERROR_MESSAGES) {
|
||||
req|= req / SQ_MSGREQ(1);
|
||||
}
|
||||
return req & (SQ_NUM|SQ_INT|SQ_CHR|SQ_BEST);
|
||||
}
|
||||
static SqRes squeeze_ret(B x) {
|
||||
return (SqRes){x, TI(x,elType)};
|
||||
}
|
||||
|
||||
// TODO randomize level of squeezing
|
||||
SqRes squeeze_numTryRand(B x, u32 req) {
|
||||
req = squeeze_processReq(req);
|
||||
u8 xe = TI(x,elType);
|
||||
if (MAY_T(req&SQ_BEST)) return squeeze_numTryImpl(x);
|
||||
if ((req&SQ_NUM) && !elNum(xe)) return squeeze_numTryImpl(x);
|
||||
if ((req&SQ_INT) && !elInt(xe)) return squeeze_numTryImpl(x);
|
||||
return squeeze_ret(x);
|
||||
}
|
||||
SqRes squeeze_chrTryRand(B x, u32 req) {
|
||||
req = squeeze_processReq(req);
|
||||
u8 xe = TI(x,elType);
|
||||
if (MAY_T(req&SQ_BEST)) return squeeze_chrTryImpl(x);
|
||||
if ((req&SQ_CHR) && !elChr(xe)) return squeeze_chrTryImpl(x);
|
||||
return squeeze_ret(x);
|
||||
}
|
||||
#endif
|
||||
@ -283,17 +283,31 @@ B squeeze_any(B x); // consumes; accepts any array, returns one with the smalles
|
||||
B squeeze_deep(B x); // consumes; accepts any object, returns an object with all parts necessary for equality checking & hashing squeezed; if this function errors due to OOM, the argument won't yet be consumed
|
||||
|
||||
typedef struct { B r; u8 re; } SqRes;
|
||||
#define SQ_UNPACK(F) SqRes r = F(x); *re_out = r.re; assert(r.re == TI(r.r,elType)); return r.r;
|
||||
|
||||
#if RANDOMIZE_HEURISTICS
|
||||
SqRes squeeze_numTryRand(B x, u32 req);
|
||||
SqRes squeeze_chrTryRand(B x, u32 req);
|
||||
#define SQ_UNPACK(F) SqRes r = F##Rand(x, req); *re_out = r.re; assert(r.re == TI(r.r,elType)); return r.r;
|
||||
#else
|
||||
SqRes squeeze_numTryImpl(B x);
|
||||
SqRes squeeze_chrTryImpl(B x);
|
||||
#define SQ_UNPACK(F) SqRes r = F##Impl(x); *re_out = r.re; assert(r.re == TI(r.r,elType)); return r.r;
|
||||
#endif
|
||||
|
||||
B squeeze_numNew(B x); // consumes; doesn't try using any existing flags; primarily intended for squeezing a newly-created array; returns bitarr for IA(x)==0
|
||||
B squeeze_chrNew(B x); // consumes; doesn't try using any existing flags; primarily intended for squeezing a newly-created array; returns c8arr for IA(x)==0
|
||||
|
||||
static B squeeze_numNewTy(u8 xe, B x) { debug_assert(TI(x,elType)==xe); return squeeze_numNew(x); } // squeeze_numNew but with a known eltype; currently eltype isn't used for anything
|
||||
|
||||
static B squeeze_numTry(B x, u8* re_out) { SQ_UNPACK(squeeze_numTryImpl) } // consumes; always returns bitarr for IA(x)==0; utilizes squoze/sortedness flags
|
||||
static B squeeze_chrTry(B x, u8* re_out) { SQ_UNPACK(squeeze_chrTryImpl) } // consumes; always returns bitarr for IA(x)==0; utilizes squoze/sortedness flags
|
||||
static B squeeze_numTry(B x, u8* re_out, u32 req) { SQ_UNPACK(squeeze_numTry) } // consumes; always returns bitarr for IA(x)==0; utilizes squoze/sortedness flags
|
||||
static B squeeze_chrTry(B x, u8* re_out, u32 req) { SQ_UNPACK(squeeze_chrTry) } // consumes; always returns bitarr for IA(x)==0; utilizes squoze flag
|
||||
// req parameter options (these matter for heuristic randomization, but otherwise are unused):
|
||||
#define SQ_ANY 0 // no requirements placed on result, i.e. can be a no-op or even widen type
|
||||
#define SQ_INT 1 // must squeeze to elInt(xe) if possible
|
||||
#define SQ_CHR 1 // must squeeze to elChr(xe) if possible
|
||||
#define SQ_NUM 2 // must squeeze to elNum(xe) if possible
|
||||
#define SQ_BEST 4 // must squeeze to smallest type possible
|
||||
#define SQ_MSGREQ(X) ((X)<<8) // if the settings in X aren't followed, different error messages may be produced
|
||||
|
||||
B squeeze_numOut(B x); // consumes; squeeze_numTry but without re_out
|
||||
B squeeze_chrOut(B x); // consumes; squeeze_chrTry but without re_out
|
||||
|
||||
@ -330,7 +330,7 @@ static u32 styG(B x) {
|
||||
if (nonChr.u!=bi_N.u) thrF("FFI: Array provided for :c%S contained %S", desc+1, genericDesc(nonChr));
|
||||
u8 xe = TI(x,elType);
|
||||
if (elChrOk(x, umax, xe)) return;
|
||||
B sq = squeeze_chrTry(incG(x), &xe);
|
||||
B sq = squeeze_chrTry(incG(x), &xe, SQ_BEST);
|
||||
bool ok = elChrOk(sq, umax, xe);
|
||||
decG(sq);
|
||||
if (!ok) {
|
||||
|
||||
@ -97,7 +97,7 @@ NOINLINE B dyArith_AA(DyTableAA* table, B w, B x) {
|
||||
case e_call_sqx: {
|
||||
u8 xe = TI(x,elType);
|
||||
assert(xe==el_f64);
|
||||
x = squeeze_numTry(x, &xe);
|
||||
x = squeeze_numTry(x, &xe, SQ_NUM);
|
||||
if (xe==el_f64) goto rec;
|
||||
e = &table->entsAA[TI(w,elType)*8 + xe];
|
||||
goto newEnt;
|
||||
@ -189,7 +189,7 @@ NOINLINE B dyArith_SA(DyTableSA* table, B w, B x) {
|
||||
case el_i8: if (wa==( u8)wa) { e=&table->ents[el_i8 ]; width=0; type=t_c8arr; goto f1; } else goto cwiden_i8;
|
||||
case el_i16: if (wa==(u16)wa) { e=&table->ents[el_i16]; width=1; type=t_c16arr; goto f1; } else goto cwiden_i16;
|
||||
case el_i32: e=&table->ents[el_i32]; width=2; type=t_c32arr; goto f1;
|
||||
case el_f64: x=squeeze_numTry(x, &xe); if (xe!=el_f64) goto newXEc; else goto rec;
|
||||
case el_f64: x=squeeze_numTry(x, &xe, SQ_CHR); if (xe!=el_f64) goto newXEc; else goto rec;
|
||||
case el_c8: if (wa==( u8)wa) { e=&table->ents[el_c8 ]; width=0; type=t_i8arr; goto f1; } goto cwiden_c8; // TODO check for & use unsigned w
|
||||
case el_c16: if (wa==(u16)wa) { e=&table->ents[el_c16]; width=1; type=t_i16arr; goto f1; } goto cwiden_c16;
|
||||
case el_c32: e=&table->ents[el_c32]; width=2; type=t_i32arr; goto f1;
|
||||
@ -288,7 +288,7 @@ static NOINLINE B or_SA(B t, B w, B x) {
|
||||
f64 wf = o2fG(w);
|
||||
return bit_sel(x, m_f64(bqn_or(wf, 0)), m_f64(bqn_or(wf, 1)));
|
||||
}
|
||||
x = squeeze_numTry(x, &xe);
|
||||
x = squeeze_numTry(x, &xe, SQ_NUM);
|
||||
if (xe==el_bit) goto bitsel;
|
||||
if (!elNum(xe)) return arith_recd(or_c2, w, x);
|
||||
x = toF64Any(x);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user