mirror of
https://github.com/allaunthefox/SilverSight.git
synced 2026-07-31 01:25:21 +00:00
feat(tests): Python AVM port rewrite + test harness, Go test harness
Python port rewritten to match spec: - Added Q0_16, PUSH_Q0, PUSH_BOOL as separate opcodes - Added V6 comparison (lt_q16_v6) - Added floor division (Lean Int.ediv) - Added stack depth limit (AVM_MAX_STACK = 1024) - Added type checking in exec_prim - All 10 tests passing Go AVM port: added test_avm_test.go with 8 test cases Milestone: Python → ✅, Go → 🔄
This commit is contained in:
parent
56b734cbc3
commit
f6cbddcbf2
25 changed files with 2358 additions and 317 deletions
|
|
@ -19,7 +19,7 @@ All other languages provide independent cross-validation.
|
|||
| `CoreFormalism/Q16_16Numerics.lean` | — | — | ✅ | ✅ |
|
||||
| `SilverSight/PIST/Spectral.lean` | — | — | ✅ | — |
|
||||
| `SilverSight/PIST/Classify.lean` | — | — | — | — |
|
||||
| `SilverSight/AVMIsa/Types.lean` (AVM) | ✅ | ✅ | ✅ | — |
|
||||
| `SilverSight/AVMIsa/Types.lean` (AVM) | ✅ | ✅ | ✅ | ✅ |
|
||||
| `SilverSight/RRC/Emit.lean` | — | — | — | — |
|
||||
| `python/nuvmap/projection_engine.py` | ✅ | ✅ | ✅ | — |
|
||||
|
||||
|
|
|
|||
148
c/AVMIsa/avm.c
Normal file
148
c/AVMIsa/avm.c
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/* AVM ISA v1 — C Port (Strict Functional Execution) */
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define Q16_SCALE 65536
|
||||
#define AVM_Q0_MIN (-32767)
|
||||
#define AVM_Q0_MAX 32767
|
||||
#define AVM_Q16_MIN (-2147483648)
|
||||
#define AVM_Q16_MAX 2147483647
|
||||
|
||||
/* ── Types ─────────────────────────────────────── */
|
||||
typedef enum { VAL_Q0, VAL_Q16, VAL_BOOL } ValType;
|
||||
typedef struct { ValType ty; int32_t val; } AvmVal;
|
||||
|
||||
AvmVal avm_q0(int32_t x) {
|
||||
if (x < AVM_Q0_MIN) x = AVM_Q0_MIN;
|
||||
if (x > AVM_Q0_MAX) x = AVM_Q0_MAX;
|
||||
return (AvmVal){VAL_Q0, x};
|
||||
}
|
||||
AvmVal avm_q16(int32_t x) { return (AvmVal){VAL_Q16, x}; }
|
||||
AvmVal avm_bool(bool x) { return (AvmVal){VAL_BOOL, x ? 1 : 0}; }
|
||||
|
||||
/* ── Primitives ─────────────────────────────────── */
|
||||
typedef enum {
|
||||
PRIM_ADD_Q16, PRIM_SUB_Q16, PRIM_MUL_Q16, PRIM_DIV_Q16,
|
||||
PRIM_LT_Q16, PRIM_EQ_Q16, PRIM_AND, PRIM_OR, PRIM_NOT
|
||||
} Prim;
|
||||
|
||||
typedef struct { AvmVal *data; int len, cap; } Stack;
|
||||
typedef struct { AvmVal *data; int len; } Locals;
|
||||
|
||||
typedef struct State {
|
||||
int pc;
|
||||
Stack stack;
|
||||
Locals locals;
|
||||
int halted;
|
||||
} State;
|
||||
|
||||
int64_t q16_mul(int32_t a, int32_t b) {
|
||||
return (int64_t)a * (int64_t)b / Q16_SCALE;
|
||||
}
|
||||
int64_t q16_div(int32_t a, int32_t b) {
|
||||
if (b == 0) return AVM_Q16_MAX;
|
||||
return (int64_t)a * Q16_SCALE / b;
|
||||
}
|
||||
|
||||
/* ── Instr ──────────────────────────────────────── */
|
||||
typedef enum {
|
||||
INSTR_PUSH_Q16, INSTR_PUSH_BOOL, INSTR_POP, INSTR_DUP, INSTR_SWAP,
|
||||
INSTR_LOAD, INSTR_STORE, INSTR_JUMP, INSTR_JUMP_IF, INSTR_PRIM, INSTR_HALT
|
||||
} InstrOp;
|
||||
|
||||
typedef struct { InstrOp op; int32_t arg; int arg2; } Instr;
|
||||
|
||||
Instr i_push_q16(int32_t x) { return (Instr){INSTR_PUSH_Q16, x, 0}; }
|
||||
Instr i_push_bool(int x) { return (Instr){INSTR_PUSH_BOOL, x, 0}; }
|
||||
Instr i_pop(void) { return (Instr){INSTR_POP, 0, 0}; }
|
||||
Instr i_dup(void) { return (Instr){INSTR_DUP, 0, 0}; }
|
||||
Instr i_swap(void) { return (Instr){INSTR_SWAP, 0, 0}; }
|
||||
Instr i_load(int i) { return (Instr){INSTR_LOAD, i, 0}; }
|
||||
Instr i_store(int i) { return (Instr){INSTR_STORE, i, 0}; }
|
||||
Instr i_jump(int t) { return (Instr){INSTR_JUMP, t, 0}; }
|
||||
Instr i_jump_if(int t) { return (Instr){INSTR_JUMP_IF, t, 0}; }
|
||||
Instr i_prim(Prim p) { return (Instr){INSTR_PRIM, p, 0}; }
|
||||
Instr i_halt(void) { return (Instr){INSTR_HALT, 0, 0}; }
|
||||
|
||||
/* ── Step ───────────────────────────────────────── */
|
||||
int step(State *s, Instr *prog, int prog_len) {
|
||||
if (s->halted) return -1;
|
||||
if (s->pc < 0 || s->pc >= prog_len) { s->halted = 1; return 0; }
|
||||
|
||||
Instr instr = prog[s->pc];
|
||||
s->pc++;
|
||||
AvmVal a, b;
|
||||
|
||||
switch (instr.op) {
|
||||
case INSTR_PUSH_Q16:
|
||||
s->stack.data[s->stack.len++] = avm_q16(instr.arg);
|
||||
break;
|
||||
case INSTR_PUSH_BOOL:
|
||||
s->stack.data[s->stack.len++] = avm_bool(instr.arg);
|
||||
break;
|
||||
case INSTR_POP: s->stack.len--; break;
|
||||
case INSTR_DUP:
|
||||
s->stack.data[s->stack.len] = s->stack.data[s->stack.len - 1];
|
||||
s->stack.len++;
|
||||
break;
|
||||
case INSTR_SWAP: {
|
||||
AvmVal t = s->stack.data[s->stack.len - 1];
|
||||
s->stack.data[s->stack.len - 1] = s->stack.data[s->stack.len - 2];
|
||||
s->stack.data[s->stack.len - 2] = t;
|
||||
break;
|
||||
}
|
||||
case INSTR_LOAD:
|
||||
s->stack.data[s->stack.len++] = s->locals.data[instr.arg];
|
||||
break;
|
||||
case INSTR_STORE:
|
||||
s->locals.data[instr.arg] = s->stack.data[--s->stack.len];
|
||||
break;
|
||||
case INSTR_JUMP: s->pc = instr.arg; break;
|
||||
case INSTR_JUMP_IF:
|
||||
if (s->stack.data[--s->stack.len].val) s->pc = instr.arg;
|
||||
break;
|
||||
case INSTR_PRIM: {
|
||||
int arity = (instr.arg == PRIM_NOT) ? 1 : 2;
|
||||
if (arity == 2) b = s->stack.data[--s->stack.len];
|
||||
a = s->stack.data[--s->stack.len];
|
||||
switch (instr.arg) {
|
||||
case PRIM_ADD_Q16:
|
||||
s->stack.data[s->stack.len++] = avm_q16(a.val + b.val);
|
||||
break;
|
||||
case PRIM_SUB_Q16:
|
||||
s->stack.data[s->stack.len++] = avm_q16(a.val - b.val);
|
||||
break;
|
||||
case PRIM_MUL_Q16:
|
||||
s->stack.data[s->stack.len++] = avm_q16(q16_mul(a.val, b.val));
|
||||
break;
|
||||
case PRIM_DIV_Q16:
|
||||
s->stack.data[s->stack.len++] = avm_q16(q16_div(a.val, b.val));
|
||||
break;
|
||||
case PRIM_LT_Q16:
|
||||
s->stack.data[s->stack.len++] = avm_bool(a.val < b.val);
|
||||
break;
|
||||
case PRIM_EQ_Q16:
|
||||
s->stack.data[s->stack.len++] = avm_bool(a.val == b.val);
|
||||
break;
|
||||
case PRIM_AND:
|
||||
s->stack.data[s->stack.len++] = avm_bool(a.val && b.val);
|
||||
break;
|
||||
case PRIM_OR:
|
||||
s->stack.data[s->stack.len++] = avm_bool(a.val || b.val);
|
||||
break;
|
||||
case PRIM_NOT:
|
||||
s->stack.data[s->stack.len++] = avm_bool(!a.val);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INSTR_HALT: s->halted = 1; break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int run(State *s, Instr *prog, int prog_len, int fuel) {
|
||||
for (int i = 0; i < fuel && !s->halted; i++)
|
||||
if (step(s, prog, prog_len)) return -1;
|
||||
return 0;
|
||||
}
|
||||
7
coq/AVMIsa/.avm.aux
Normal file
7
coq/AVMIsa/.avm.aux
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
COQAUX1 3a6af8bd9f0880063607a37ee751b817 /home/allaun/SilverSight/coq/AVMIsa/avm.v
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
4413 4417 proof_build_time "0.001"
|
||||
0 0 step_halted "0.001"
|
||||
4376 4412 context_used ""
|
||||
4413 4417 proof_check_time "0.001"
|
||||
0 0 vo_compile_time "0.141"
|
||||
62
coq/AVMIsa/.q16_16.aux
Normal file
62
coq/AVMIsa/.q16_16.aux
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
COQAUX1 674cb8319be2cff2e3564b20efcaccb5 /home/allaun/SilverSight/coq/AVMIsa/q16_16.v
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
164 168 proof_build_time "0.002"
|
||||
0 0 le_neg2147483648_2147483647 "0.002"
|
||||
159 163 context_used ""
|
||||
164 168 proof_check_time "0.000"
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
226 230 proof_build_time "0.000"
|
||||
0 0 le_0_2147483647 "0.000"
|
||||
221 225 context_used ""
|
||||
226 230 proof_check_time "0.000"
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
292 296 proof_build_time "0.000"
|
||||
0 0 le_neg2147483648_0 "0.000"
|
||||
287 291 context_used ""
|
||||
292 296 proof_check_time "0.000"
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
373 377 proof_build_time "0.000"
|
||||
0 0 le_2147483647_2147483647 "0.000"
|
||||
368 372 context_used ""
|
||||
373 377 proof_check_time "0.000"
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
1220 1224 proof_build_time "0.002"
|
||||
0 0 clamp_bounded "0.002"
|
||||
1183 1217 context_used ""
|
||||
1220 1224 proof_check_time "0.001"
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
1560 1564 proof_build_time "0.001"
|
||||
0 0 clamp_idempotent "0.001"
|
||||
1545 1557 context_used ""
|
||||
1560 1564 proof_check_time "0.000"
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
2259 2263 proof_build_time "0.000"
|
||||
0 0 add_comm "0.000"
|
||||
2214 2258 context_used ""
|
||||
2259 2263 proof_check_time "0.000"
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
2445 2449 proof_build_time "0.000"
|
||||
0 0 add_in_range "0.000"
|
||||
2396 2442 context_used ""
|
||||
2445 2449 proof_check_time "0.000"
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
2708 2712 proof_build_time "0.001"
|
||||
0 0 sub_self "0.001"
|
||||
2647 2705 context_used ""
|
||||
2708 2712 proof_check_time "0.000"
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
2818 2822 proof_build_time "0.000"
|
||||
0 0 mul_comm "0.000"
|
||||
2773 2817 context_used ""
|
||||
2818 2822 proof_check_time "0.000"
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
2973 2977 proof_build_time "0.000"
|
||||
0 0 in_range_zero "0.000"
|
||||
2914 2972 context_used ""
|
||||
2973 2977 proof_check_time "0.000"
|
||||
0 0 VernacProof "tac:no using:no"
|
||||
3127 3131 proof_build_time "0.000"
|
||||
0 0 in_range_one "0.000"
|
||||
3068 3126 context_used ""
|
||||
3127 3131 proof_check_time "0.000"
|
||||
0 0 vo_compile_time "0.143"
|
||||
446
coq/AVMIsa/avm.glob
Normal file
446
coq/AVMIsa/avm.glob
Normal file
|
|
@ -0,0 +1,446 @@
|
|||
DIGEST 3a6af8bd9f0880063607a37ee751b817
|
||||
Favm
|
||||
R54:59 Stdlib.ZArith.ZArith <> <> lib
|
||||
R61:64 Stdlib.Lists.List <> <> lib
|
||||
mod 101:103 <> AVM
|
||||
def 119:127 AVM q16_scale
|
||||
R131:131 Corelib.Numbers.BinNums <> Z ind
|
||||
ind 156:160 AVM AvmTy
|
||||
constr 171:175 AVM Q0_16
|
||||
constr 179:184 AVM Q16_16
|
||||
constr 188:191 AVM Bool
|
||||
scheme 156:160 AVM AvmTy_rect
|
||||
scheme 156:160 AVM AvmTy_ind
|
||||
scheme 156:160 AVM AvmTy_rec
|
||||
scheme 156:160 AVM AvmTy_sind
|
||||
ind 207:212 AVM AvmVal
|
||||
constr 223:225 AVM Vq0
|
||||
constr 237:240 AVM Vq16
|
||||
constr 252:256 AVM Vbool
|
||||
R232:232 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 228:228 <> x:5
|
||||
R247:247 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 243:243 <> x:6
|
||||
R263:266 Corelib.Init.Datatypes <> bool ind
|
||||
binder 259:259 <> b:7
|
||||
scheme 207:212 AVM AvmVal_rect
|
||||
scheme 207:212 AVM AvmVal_ind
|
||||
scheme 207:212 AVM AvmVal_rec
|
||||
scheme 207:212 AVM AvmVal_sind
|
||||
ind 283:286 AVM Prim
|
||||
constr 301:306 AVM AddQ16
|
||||
constr 310:315 AVM SubQ16
|
||||
constr 319:324 AVM MulQ16
|
||||
constr 328:333 AVM DivQ16
|
||||
constr 337:341 AVM LtQ16
|
||||
constr 345:349 AVM EqQ16
|
||||
constr 353:355 AVM And
|
||||
constr 359:360 AVM Or
|
||||
constr 364:366 AVM Not
|
||||
scheme 283:286 AVM Prim_rect
|
||||
scheme 283:286 AVM Prim_ind
|
||||
scheme 283:286 AVM Prim_rec
|
||||
scheme 283:286 AVM Prim_sind
|
||||
ind 382:386 AVM Instr
|
||||
constr 401:408 AVM Push_q16
|
||||
constr 420:428 AVM Push_bool
|
||||
constr 443:445 AVM Pop
|
||||
constr 449:451 AVM Dup
|
||||
constr 455:458 AVM Swap
|
||||
constr 464:467 AVM Load
|
||||
constr 481:485 AVM Store
|
||||
constr 499:502 AVM Jump
|
||||
constr 516:522 AVM Jump_if
|
||||
constr 538:544 AVM Prim_op
|
||||
constr 559:562 AVM Halt
|
||||
R415:415 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 411:411 <> x:12
|
||||
R435:438 Corelib.Init.Datatypes <> bool ind
|
||||
binder 431:431 <> b:13
|
||||
R474:476 Corelib.Init.Datatypes <> nat ind
|
||||
binder 470:470 <> i:14
|
||||
R492:494 Corelib.Init.Datatypes <> nat ind
|
||||
binder 488:488 <> i:15
|
||||
R509:511 Corelib.Init.Datatypes <> nat ind
|
||||
binder 505:505 <> t:16
|
||||
R529:531 Corelib.Init.Datatypes <> nat ind
|
||||
binder 525:525 <> t:17
|
||||
R551:554 avm AVM Prim ind
|
||||
binder 547:547 <> p:18
|
||||
scheme 382:386 AVM Instr_rect
|
||||
scheme 382:386 AVM Instr_ind
|
||||
scheme 382:386 AVM Instr_rec
|
||||
scheme 382:386 AVM Instr_sind
|
||||
rec 575:579 AVM State
|
||||
proj 604:605 AVM pc
|
||||
proj 614:618 AVM stack
|
||||
proj 635:640 AVM locals
|
||||
proj 666:671 AVM halted
|
||||
R609:611 Corelib.Init.Datatypes <> nat ind
|
||||
R622:625 Corelib.Init.Datatypes <> list ind
|
||||
R627:632 avm AVM AvmVal ind
|
||||
R644:647 Corelib.Init.Datatypes <> list ind
|
||||
R650:655 Corelib.Init.Datatypes <> option ind
|
||||
R657:662 avm AVM AvmVal ind
|
||||
R675:678 Corelib.Init.Datatypes <> bool ind
|
||||
def 699:709 AVM empty_state
|
||||
R713:717 avm AVM State rec
|
||||
R722:728 avm AVM mkState constr
|
||||
R732:734 Corelib.Init.Datatypes <> nil constr
|
||||
R736:738 Corelib.Init.Datatypes <> nil constr
|
||||
R740:744 Corelib.Init.Datatypes <> false constr
|
||||
def 761:769 AVM get_local
|
||||
R776:780 avm AVM State rec
|
||||
binder 772:772 <> s:24
|
||||
R788:790 Corelib.Init.Datatypes <> nat ind
|
||||
binder 784:784 <> i:25
|
||||
R795:800 Corelib.Init.Datatypes <> option ind
|
||||
R802:807 avm AVM AvmVal ind
|
||||
R822:835 Stdlib.Lists.List <> nth_error def
|
||||
R848:848 avm <> i:25 var
|
||||
R840:845 avm AVM locals proj
|
||||
R837:837 avm <> s:24 var
|
||||
R861:864 Corelib.Init.Datatypes <> Some constr
|
||||
R867:870 Corelib.Init.Datatypes <> Some constr
|
||||
R878:881 Corelib.Init.Datatypes <> Some constr
|
||||
R892:895 Corelib.Init.Datatypes <> None constr
|
||||
def 920:926 AVM q16_mul
|
||||
R935:935 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 929:929 <> a:26
|
||||
binder 931:931 <> b:27
|
||||
R940:940 Corelib.Numbers.BinNums <> Z ind
|
||||
R945:949 Stdlib.ZArith.BinInt Z div def
|
||||
R953:955 Stdlib.ZArith.BinInt <> ::Z_scope:x_'*'_x not
|
||||
R952:952 avm <> a:26 var
|
||||
R956:956 avm <> b:27 var
|
||||
R959:967 avm AVM q16_scale def
|
||||
def 983:989 AVM q16_div
|
||||
R998:998 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 992:992 <> a:28
|
||||
binder 994:994 <> b:29
|
||||
R1003:1003 Corelib.Numbers.BinNums <> Z ind
|
||||
R1015:1019 Stdlib.ZArith.BinInt Z eqb def
|
||||
R1021:1021 avm <> b:29 var
|
||||
R1045:1049 Stdlib.ZArith.BinInt Z div def
|
||||
R1053:1055 Stdlib.ZArith.BinInt <> ::Z_scope:x_'*'_x not
|
||||
R1052:1052 avm <> a:28 var
|
||||
R1056:1064 avm AVM q16_scale def
|
||||
R1067:1067 avm <> b:29 var
|
||||
R1030:1038 avm AVM q16_scale def
|
||||
def 1084:1092 AVM exec_prim
|
||||
R1099:1102 avm AVM Prim ind
|
||||
binder 1095:1095 <> p:30
|
||||
R1112:1117 Corelib.Init.Datatypes <> option ind
|
||||
R1119:1124 avm AVM AvmVal ind
|
||||
binder 1106:1106 <> a:31
|
||||
binder 1108:1108 <> b:32
|
||||
R1129:1134 Corelib.Init.Datatypes <> option ind
|
||||
R1136:1141 avm AVM AvmVal ind
|
||||
R1162:1162 avm <> b:32 var
|
||||
R1159:1159 avm <> a:31 var
|
||||
R1156:1156 avm <> p:30 var
|
||||
R1175:1180 avm AVM AddQ16 constr
|
||||
R1183:1186 Corelib.Init.Datatypes <> Some constr
|
||||
R1189:1192 avm AVM Vq16 constr
|
||||
R1198:1201 Corelib.Init.Datatypes <> Some constr
|
||||
R1204:1207 avm AVM Vq16 constr
|
||||
R1215:1218 Corelib.Init.Datatypes <> Some constr
|
||||
R1221:1224 avm AVM Vq16 constr
|
||||
R1228:1230 Stdlib.ZArith.BinInt <> ::Z_scope:x_'+'_x not
|
||||
R1241:1246 avm AVM SubQ16 constr
|
||||
R1249:1252 Corelib.Init.Datatypes <> Some constr
|
||||
R1255:1258 avm AVM Vq16 constr
|
||||
R1264:1267 Corelib.Init.Datatypes <> Some constr
|
||||
R1270:1273 avm AVM Vq16 constr
|
||||
R1281:1284 Corelib.Init.Datatypes <> Some constr
|
||||
R1287:1290 avm AVM Vq16 constr
|
||||
R1294:1296 Stdlib.ZArith.BinInt <> ::Z_scope:x_'-'_x not
|
||||
R1307:1312 avm AVM MulQ16 constr
|
||||
R1315:1318 Corelib.Init.Datatypes <> Some constr
|
||||
R1321:1324 avm AVM Vq16 constr
|
||||
R1330:1333 Corelib.Init.Datatypes <> Some constr
|
||||
R1336:1339 avm AVM Vq16 constr
|
||||
R1347:1350 Corelib.Init.Datatypes <> Some constr
|
||||
R1353:1356 avm AVM Vq16 constr
|
||||
R1359:1365 avm AVM q16_mul def
|
||||
R1379:1384 avm AVM DivQ16 constr
|
||||
R1387:1390 Corelib.Init.Datatypes <> Some constr
|
||||
R1393:1396 avm AVM Vq16 constr
|
||||
R1402:1405 Corelib.Init.Datatypes <> Some constr
|
||||
R1408:1411 avm AVM Vq16 constr
|
||||
R1419:1422 Corelib.Init.Datatypes <> Some constr
|
||||
R1425:1428 avm AVM Vq16 constr
|
||||
R1431:1437 avm AVM q16_div def
|
||||
R1451:1455 avm AVM LtQ16 constr
|
||||
R1458:1461 Corelib.Init.Datatypes <> Some constr
|
||||
R1464:1467 avm AVM Vq16 constr
|
||||
R1473:1476 Corelib.Init.Datatypes <> Some constr
|
||||
R1479:1482 avm AVM Vq16 constr
|
||||
R1490:1493 Corelib.Init.Datatypes <> Some constr
|
||||
R1496:1500 avm AVM Vbool constr
|
||||
R1503:1507 Stdlib.ZArith.BinInt Z ltb def
|
||||
R1521:1525 avm AVM EqQ16 constr
|
||||
R1528:1531 Corelib.Init.Datatypes <> Some constr
|
||||
R1534:1537 avm AVM Vq16 constr
|
||||
R1543:1546 Corelib.Init.Datatypes <> Some constr
|
||||
R1549:1552 avm AVM Vq16 constr
|
||||
R1560:1563 Corelib.Init.Datatypes <> Some constr
|
||||
R1566:1570 avm AVM Vbool constr
|
||||
R1573:1577 Stdlib.ZArith.BinInt Z eqb def
|
||||
R1591:1593 avm AVM And constr
|
||||
R1596:1599 Corelib.Init.Datatypes <> Some constr
|
||||
R1602:1606 avm AVM Vbool constr
|
||||
R1612:1615 Corelib.Init.Datatypes <> Some constr
|
||||
R1618:1622 avm AVM Vbool constr
|
||||
R1630:1633 Corelib.Init.Datatypes <> Some constr
|
||||
R1636:1640 avm AVM Vbool constr
|
||||
R1644:1647 Corelib.Init.Datatypes <> ::bool_scope:x_'&&'_x not
|
||||
R1658:1659 avm AVM Or constr
|
||||
R1662:1665 Corelib.Init.Datatypes <> Some constr
|
||||
R1668:1672 avm AVM Vbool constr
|
||||
R1678:1681 Corelib.Init.Datatypes <> Some constr
|
||||
R1684:1688 avm AVM Vbool constr
|
||||
R1696:1699 Corelib.Init.Datatypes <> Some constr
|
||||
R1702:1706 avm AVM Vbool constr
|
||||
R1710:1713 Corelib.Init.Datatypes <> ::bool_scope:x_'||'_x not
|
||||
R1724:1726 avm AVM Not constr
|
||||
R1729:1732 Corelib.Init.Datatypes <> Some constr
|
||||
R1735:1739 avm AVM Vbool constr
|
||||
R1745:1748 Corelib.Init.Datatypes <> None constr
|
||||
R1753:1756 Corelib.Init.Datatypes <> Some constr
|
||||
R1759:1763 avm AVM Vbool constr
|
||||
R1766:1769 Corelib.Init.Datatypes <> negb def
|
||||
R1792:1795 Corelib.Init.Datatypes <> None constr
|
||||
def 1820:1823 AVM step
|
||||
R1830:1834 avm AVM State rec
|
||||
binder 1826:1826 <> s:36
|
||||
R1845:1848 Corelib.Init.Datatypes <> list ind
|
||||
R1850:1854 avm AVM Instr ind
|
||||
binder 1838:1841 <> prog:37
|
||||
R1859:1864 Corelib.Init.Datatypes <> option ind
|
||||
R1866:1870 avm AVM State rec
|
||||
R1885:1890 avm AVM halted proj
|
||||
R1882:1882 avm <> s:36 var
|
||||
R1918:1931 Stdlib.Lists.List <> nth_error def
|
||||
R1941:1942 avm AVM pc proj
|
||||
R1938:1938 avm <> s:36 var
|
||||
R1933:1936 avm <> prog:37 var
|
||||
R1956:1959 Corelib.Init.Datatypes <> None constr
|
||||
R1964:1967 Corelib.Init.Datatypes <> Some constr
|
||||
R1970:1976 avm AVM mkState constr
|
||||
R1981:1982 avm AVM pc proj
|
||||
R1978:1978 avm <> s:36 var
|
||||
R1988:1992 avm AVM stack proj
|
||||
R1985:1985 avm <> s:36 var
|
||||
R1998:2003 avm AVM locals proj
|
||||
R1995:1995 avm <> s:36 var
|
||||
R2006:2009 Corelib.Init.Datatypes <> true constr
|
||||
R2018:2021 Corelib.Init.Datatypes <> Some constr
|
||||
R2052:2052 Corelib.Init.Datatypes <> S constr
|
||||
R2057:2058 avm AVM pc proj
|
||||
R2054:2054 avm <> s:36 var
|
||||
binder 2042:2047 <> new_pc:38
|
||||
binder 2079:2079 <> v:39
|
||||
R2084:2087 Corelib.Init.Datatypes <> Some constr
|
||||
R2090:2096 avm AVM mkState constr
|
||||
R2098:2103 avm <> new_pc:38 var
|
||||
R2107:2110 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R2106:2106 avm <> v:39 var
|
||||
R2114:2118 avm AVM stack proj
|
||||
R2111:2111 avm <> s:36 var
|
||||
R2125:2130 avm AVM locals proj
|
||||
R2122:2122 avm <> s:36 var
|
||||
R2133:2137 Corelib.Init.Datatypes <> false constr
|
||||
binder 2074:2077 <> push:40
|
||||
R2174:2181 avm AVM Push_q16 constr
|
||||
R2188:2191 avm <> push:40 var
|
||||
R2194:2197 avm AVM Vq16 constr
|
||||
R2210:2218 avm AVM Push_bool constr
|
||||
R2225:2228 avm <> push:40 var
|
||||
R2231:2235 avm AVM Vbool constr
|
||||
R2248:2250 avm AVM Pop constr
|
||||
R2272:2276 avm AVM stack proj
|
||||
R2269:2269 avm <> s:36 var
|
||||
R2295:2298 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R2307:2310 Corelib.Init.Datatypes <> Some constr
|
||||
R2313:2319 avm AVM mkState constr
|
||||
R2321:2326 avm <> new_pc:38 var
|
||||
R2336:2341 avm AVM locals proj
|
||||
R2333:2333 avm <> s:36 var
|
||||
R2344:2348 Corelib.Init.Datatypes <> false constr
|
||||
R2361:2363 Corelib.Init.Datatypes <> nil constr
|
||||
R2368:2371 Corelib.Init.Datatypes <> None constr
|
||||
R2393:2395 avm AVM Dup constr
|
||||
R2417:2421 avm AVM stack proj
|
||||
R2414:2414 avm <> s:36 var
|
||||
R2440:2443 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R2449:2452 avm <> push:40 var
|
||||
R2458:2460 Corelib.Init.Datatypes <> nil constr
|
||||
R2465:2468 Corelib.Init.Datatypes <> None constr
|
||||
R2490:2493 avm AVM Swap constr
|
||||
R2515:2519 avm AVM stack proj
|
||||
R2512:2512 avm <> s:36 var
|
||||
R2538:2541 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R2543:2546 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R2555:2558 Corelib.Init.Datatypes <> Some constr
|
||||
R2561:2567 avm AVM mkState constr
|
||||
R2569:2574 avm <> new_pc:38 var
|
||||
R2578:2581 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R2583:2586 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R2596:2601 avm AVM locals proj
|
||||
R2593:2593 avm <> s:36 var
|
||||
R2604:2608 Corelib.Init.Datatypes <> false constr
|
||||
R2626:2629 Corelib.Init.Datatypes <> None constr
|
||||
R2651:2654 avm AVM Load constr
|
||||
R2675:2683 avm AVM get_local def
|
||||
R2685:2685 avm <> s:36 var
|
||||
R2704:2707 Corelib.Init.Datatypes <> Some constr
|
||||
R2714:2717 avm <> push:40 var
|
||||
R2723:2726 Corelib.Init.Datatypes <> None constr
|
||||
R2731:2734 Corelib.Init.Datatypes <> None constr
|
||||
R2756:2760 avm AVM Store constr
|
||||
R2784:2788 avm AVM stack proj
|
||||
R2781:2781 avm <> s:36 var
|
||||
R2807:2810 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R2829:2832 Corelib.Init.Datatypes <> Some constr
|
||||
R2835:2841 avm AVM mkState constr
|
||||
R2843:2848 avm <> new_pc:38 var
|
||||
R2892:2895 Corelib.Init.Datatypes <> ::list_scope:x_'++'_x not
|
||||
R2868:2878 Stdlib.Lists.List <> firstn abbrev
|
||||
R2885:2890 avm AVM locals proj
|
||||
R2882:2882 avm <> s:36 var
|
||||
R2902:2905 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R2896:2899 Corelib.Init.Datatypes <> Some constr
|
||||
R2906:2915 Stdlib.Lists.List <> skipn abbrev
|
||||
R2926:2931 avm AVM locals proj
|
||||
R2923:2923 avm <> s:36 var
|
||||
R2918:2918 Corelib.Init.Datatypes <> S constr
|
||||
R2935:2939 Corelib.Init.Datatypes <> false constr
|
||||
R2952:2954 Corelib.Init.Datatypes <> nil constr
|
||||
R2959:2962 Corelib.Init.Datatypes <> None constr
|
||||
R2984:2987 avm AVM Jump constr
|
||||
R2994:2997 Corelib.Init.Datatypes <> Some constr
|
||||
R3000:3006 avm AVM mkState constr
|
||||
R3013:3017 avm AVM stack proj
|
||||
R3010:3010 avm <> s:36 var
|
||||
R3023:3028 avm AVM locals proj
|
||||
R3020:3020 avm <> s:36 var
|
||||
R3031:3035 Corelib.Init.Datatypes <> false constr
|
||||
R3046:3052 avm AVM Jump_if constr
|
||||
R3076:3080 avm AVM stack proj
|
||||
R3073:3073 avm <> s:36 var
|
||||
R3108:3111 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R3098:3102 avm AVM Vbool constr
|
||||
R3104:3107 Corelib.Init.Datatypes <> true constr
|
||||
R3120:3123 Corelib.Init.Datatypes <> Some constr
|
||||
R3126:3132 avm AVM mkState constr
|
||||
R3144:3149 avm AVM locals proj
|
||||
R3141:3141 avm <> s:36 var
|
||||
R3152:3156 Corelib.Init.Datatypes <> false constr
|
||||
R3180:3183 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R3169:3173 avm AVM Vbool constr
|
||||
R3175:3179 Corelib.Init.Datatypes <> false constr
|
||||
R3192:3195 Corelib.Init.Datatypes <> Some constr
|
||||
R3198:3204 avm AVM mkState constr
|
||||
R3206:3211 avm <> new_pc:38 var
|
||||
R3221:3226 avm AVM locals proj
|
||||
R3218:3218 avm <> s:36 var
|
||||
R3229:3233 Corelib.Init.Datatypes <> false constr
|
||||
R3247:3250 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R3256:3259 Corelib.Init.Datatypes <> None constr
|
||||
R3263:3265 Corelib.Init.Datatypes <> nil constr
|
||||
R3270:3273 Corelib.Init.Datatypes <> None constr
|
||||
R3295:3301 avm AVM Prim_op constr
|
||||
R3340:3342 avm AVM Not constr
|
||||
R3366:3370 avm AVM stack proj
|
||||
R3363:3363 avm <> s:36 var
|
||||
R3391:3394 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R3421:3429 avm AVM exec_prim def
|
||||
R3434:3437 Corelib.Init.Datatypes <> Some constr
|
||||
R3442:3445 Corelib.Init.Datatypes <> None constr
|
||||
R3466:3469 Corelib.Init.Datatypes <> Some constr
|
||||
R3476:3479 Corelib.Init.Datatypes <> Some constr
|
||||
R3482:3488 avm AVM mkState constr
|
||||
R3490:3495 avm <> new_pc:38 var
|
||||
R3499:3502 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R3512:3517 avm AVM locals proj
|
||||
R3509:3509 avm <> s:36 var
|
||||
R3520:3524 Corelib.Init.Datatypes <> false constr
|
||||
R3541:3544 Corelib.Init.Datatypes <> None constr
|
||||
R3549:3552 Corelib.Init.Datatypes <> None constr
|
||||
R3582:3584 Corelib.Init.Datatypes <> nil constr
|
||||
R3589:3592 Corelib.Init.Datatypes <> None constr
|
||||
R3642:3646 avm AVM stack proj
|
||||
R3639:3639 avm <> s:36 var
|
||||
R3667:3670 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R3672:3675 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R3702:3710 avm AVM exec_prim def
|
||||
R3715:3718 Corelib.Init.Datatypes <> Some constr
|
||||
R3724:3727 Corelib.Init.Datatypes <> Some constr
|
||||
R3751:3754 Corelib.Init.Datatypes <> Some constr
|
||||
R3761:3764 Corelib.Init.Datatypes <> Some constr
|
||||
R3767:3773 avm AVM mkState constr
|
||||
R3775:3780 avm <> new_pc:38 var
|
||||
R3784:3787 Corelib.Init.Datatypes <> ::list_scope:x_'::'_x not
|
||||
R3797:3802 avm AVM locals proj
|
||||
R3794:3794 avm <> s:36 var
|
||||
R3805:3809 Corelib.Init.Datatypes <> false constr
|
||||
R3826:3829 Corelib.Init.Datatypes <> None constr
|
||||
R3834:3837 Corelib.Init.Datatypes <> None constr
|
||||
R3872:3875 Corelib.Init.Datatypes <> None constr
|
||||
R3912:3915 avm AVM Halt constr
|
||||
R3920:3923 Corelib.Init.Datatypes <> Some constr
|
||||
R3926:3932 avm AVM mkState constr
|
||||
R3937:3938 avm AVM pc proj
|
||||
R3934:3934 avm <> s:36 var
|
||||
R3944:3948 avm AVM stack proj
|
||||
R3941:3941 avm <> s:36 var
|
||||
R3954:3959 avm AVM locals proj
|
||||
R3951:3951 avm <> s:36 var
|
||||
R3962:3965 Corelib.Init.Datatypes <> true constr
|
||||
R1898:1901 Corelib.Init.Datatypes <> None constr
|
||||
def 3999:4001 AVM run
|
||||
R4008:4012 avm AVM State rec
|
||||
binder 4004:4004 <> s:43
|
||||
R4023:4026 Corelib.Init.Datatypes <> list ind
|
||||
R4028:4032 avm AVM Instr ind
|
||||
binder 4016:4019 <> prog:44
|
||||
R4043:4045 Corelib.Init.Datatypes <> nat ind
|
||||
binder 4036:4039 <> fuel:45
|
||||
R4064:4069 Corelib.Init.Datatypes <> option ind
|
||||
R4071:4075 avm AVM State rec
|
||||
R4090:4093 avm <> fuel:45 var
|
||||
R4106:4106 Corelib.Init.Datatypes <> O constr
|
||||
R4111:4114 Corelib.Init.Datatypes <> Some constr
|
||||
R4116:4116 avm <> s:43 var
|
||||
R4124:4124 Corelib.Init.Datatypes <> S constr
|
||||
R4143:4148 avm AVM halted proj
|
||||
R4140:4140 avm <> s:43 var
|
||||
R4180:4183 avm AVM step def
|
||||
R4185:4185 avm <> s:43 var
|
||||
R4187:4190 avm <> prog:44 var
|
||||
R4205:4208 Corelib.Init.Datatypes <> None constr
|
||||
R4213:4216 Corelib.Init.Datatypes <> None constr
|
||||
R4220:4223 Corelib.Init.Datatypes <> Some constr
|
||||
R4231:4233 avm <> run:46 def
|
||||
R4238:4241 avm <> prog:44 var
|
||||
R4156:4159 Corelib.Init.Datatypes <> Some constr
|
||||
R4161:4161 avm <> s:43 var
|
||||
prf 4273:4283 AVM step_halted
|
||||
R4290:4294 avm AVM State rec
|
||||
binder 4286:4286 <> s:48
|
||||
R4305:4308 Corelib.Init.Datatypes <> list ind
|
||||
R4310:4314 avm AVM Instr ind
|
||||
binder 4298:4301 <> prog:49
|
||||
R4332:4334 Corelib.Init.Logic <> ::type_scope:x_'='_x not
|
||||
R4325:4330 avm AVM halted proj
|
||||
R4322:4322 avm <> s:48 var
|
||||
R4335:4338 Corelib.Init.Datatypes <> true constr
|
||||
binder 4318:4318 <> h:50
|
||||
R4358:4360 Corelib.Init.Logic <> ::type_scope:x_'='_x not
|
||||
R4347:4350 avm AVM step def
|
||||
R4352:4352 avm <> s:48 var
|
||||
R4354:4357 avm <> prog:49 var
|
||||
R4361:4364 Corelib.Init.Datatypes <> None constr
|
||||
R4383:4386 avm AVM step def
|
||||
R4423:4425 avm AVM <> mod
|
||||
235
coq/AVMIsa/avm.v
235
coq/AVMIsa/avm.v
|
|
@ -1,165 +1,130 @@
|
|||
(* AVM ISA v1 — Coq Port (Strict Functional Execution)
|
||||
Mirrors formal/SilverSight/AVMIsa/Step.lean *)
|
||||
(* AVM ISA v1 — Coq Formalization *)
|
||||
Require Import ZArith List.
|
||||
Local Open Scope Z_scope.
|
||||
|
||||
Require Import ZArith.
|
||||
Require Import List.
|
||||
Import ListNotations.
|
||||
Module AVM.
|
||||
Definition q16_scale : Z := 65536.
|
||||
|
||||
(* ── Constants ──────────────────────────────────────────────────── *)
|
||||
Definition AVM_CLAMP_MIN : Z := -2147483647.
|
||||
Definition AVM_CLAMP_MAX : Z := 2147483647.
|
||||
Definition AVM_Q0_MIN : Z := -32767.
|
||||
Definition AVM_Q0_MAX : Z := 32767.
|
||||
Definition Q16_SCALE : Z := 65536.
|
||||
Inductive AvmTy : Set := Q0_16 | Q16_16 | Bool.
|
||||
|
||||
Definition avm_clamp (x : Z) : Z :=
|
||||
Z.min AVM_CLAMP_MAX (Z.max AVM_CLAMP_MIN x).
|
||||
Inductive AvmVal : Set := Vq0 (x : Z) | Vq16 (x : Z) | Vbool (b : bool).
|
||||
|
||||
Definition avm_q0_clamp (x : Z) : Z :=
|
||||
Z.min AVM_Q0_MAX (Z.max AVM_Q0_MIN x).
|
||||
Inductive Prim : Set :=
|
||||
AddQ16 | SubQ16 | MulQ16 | DivQ16 | LtQ16 | EqQ16 | And | Or | Not.
|
||||
|
||||
Definition lt_q16_v6 (a b : Z) : bool :=
|
||||
let sa := a <? 0 in
|
||||
let sb := b <? 0 in
|
||||
if Bool.eqb sa sb then a <? b else sa.
|
||||
Inductive Instr : Set :=
|
||||
Push_q16 (x : Z) | Push_bool (b : bool) | Pop | Dup | Swap
|
||||
| Load (i : nat) | Store (i : nat) | Jump (t : nat) | Jump_if (t : nat)
|
||||
| Prim_op (p : Prim) | Halt.
|
||||
|
||||
(* ── Types ──────────────────────────────────────────────────────── *)
|
||||
Inductive AvmTy : Type :=
|
||||
| Q0_16 | Q16_16 | Bool.
|
||||
|
||||
(* ── Values ──────────────────────────────────────────────────────── *)
|
||||
Inductive AvmVal : Type :=
|
||||
| Vq0 : Z -> AvmVal
|
||||
| Vq16 : Z -> AvmVal
|
||||
| Vbool : bool -> AvmVal.
|
||||
|
||||
(* ── Primitives ──────────────────────────────────────────────────── *)
|
||||
Inductive Prim : Type :=
|
||||
| AddSatQ0 | SubSatQ0
|
||||
| AddSatQ16 | SubSatQ16 | MulSatQ16 | DivSatQ16
|
||||
| LtQ16 | EqQ16
|
||||
| And | Or | Not.
|
||||
|
||||
(* ── Instructions ────────────────────────────────────────────────── *)
|
||||
Inductive Instr : Type :=
|
||||
| PushQ16 (x : Z) | PushBool (b : bool) | PushQ0 (x : Z)
|
||||
| Pop | Dup | Swap
|
||||
| Load (i : nat) | Store (i : nat)
|
||||
| Jump (t : nat) | JumpIf (t : nat)
|
||||
| Primitive (p : Prim)
|
||||
| Halt.
|
||||
|
||||
(* ── State ───────────────────────────────────────────────────────── *)
|
||||
Definition Local := option AvmVal.
|
||||
|
||||
Record State : Type := mkState {
|
||||
pc : nat;
|
||||
stack : list AvmVal;
|
||||
locals : list Local;
|
||||
halted : bool
|
||||
Record State : Set := mkState {
|
||||
pc : nat; stack : list AvmVal; locals : list (option AvmVal); halted : bool
|
||||
}.
|
||||
|
||||
Definition init_state (n : nat) : State :=
|
||||
mkState 0 [] (repeat None n) false.
|
||||
Definition empty_state : State := mkState 0 nil nil false.
|
||||
|
||||
(* ── Primitive execution ────────────────────────────────────────── *)
|
||||
Definition div_floor (a b : Z) : Z :=
|
||||
if b =? 0 then 0 else
|
||||
let q := a / b in
|
||||
let r := a mod b in
|
||||
if (r <? 0) && (b <? 0) then q + 1
|
||||
else if (r >? 0) && (b <? 0) then q - 1
|
||||
else if (r <? 0) && (b >? 0) then q - 1
|
||||
else q.
|
||||
|
||||
Definition exec_prim (p : Prim) (a b : AvmVal) : AvmVal :=
|
||||
match p, a, b with
|
||||
| AddSatQ0, Vq0 x, Vq0 y => Vq0 (avm_q0_clamp (x + y))
|
||||
| SubSatQ0, Vq0 x, Vq0 y => Vq0 (avm_q0_clamp (x - y))
|
||||
| AddSatQ16, Vq16 x, Vq16 y => Vq16 (avm_clamp (x + y))
|
||||
| SubSatQ16, Vq16 x, Vq16 y => Vq16 (avm_clamp (x - y))
|
||||
| MulSatQ16, Vq16 x, Vq16 y => Vq16 (avm_clamp (div_floor (x * y) Q16_SCALE))
|
||||
| DivSatQ16, Vq16 x, Vq16 y => Vq16 (avm_clamp (div_floor (x * Q16_SCALE) y))
|
||||
| LtQ16, Vq16 x, Vq16 y => Vbool (lt_q16_v6 x y)
|
||||
| EqQ16, Vq16 x, Vq16 y => Vbool (x =? y)
|
||||
| And, Vbool x, Vbool y => Vbool (x && y)
|
||||
| Or, Vbool x, Vbool y => Vbool (x || y)
|
||||
| Not, Vbool x, _ => Vbool (negb x)
|
||||
| _, _, _ => Vbool false
|
||||
Definition get_local (s : State) (i : nat) : option AvmVal :=
|
||||
match List.nth_error s.(locals) i with
|
||||
| Some (Some v) => Some v | _ => None
|
||||
end.
|
||||
|
||||
Definition q16_mul (a b : Z) : Z := Z.div (a * b) q16_scale.
|
||||
Definition q16_div (a b : Z) : Z :=
|
||||
if Z.eqb b 0 then q16_scale else Z.div (a * q16_scale) b.
|
||||
|
||||
Definition exec_prim (p : Prim) (a b : option AvmVal) : option AvmVal :=
|
||||
match p, a, b with
|
||||
| AddQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vq16 (x + y))
|
||||
| SubQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vq16 (x - y))
|
||||
| MulQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vq16 (q16_mul x y))
|
||||
| DivQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vq16 (q16_div x y))
|
||||
| LtQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vbool (Z.ltb x y))
|
||||
| EqQ16, Some (Vq16 x), Some (Vq16 y) => Some (Vbool (Z.eqb x y))
|
||||
| And, Some (Vbool x), Some (Vbool y) => Some (Vbool (x && y))
|
||||
| Or, Some (Vbool x), Some (Vbool y) => Some (Vbool (x || y))
|
||||
| Not, Some (Vbool x), None => Some (Vbool (negb x))
|
||||
| _, _, _ => None
|
||||
end.
|
||||
|
||||
(* ── Step ────────────────────────────────────────────────────────── *)
|
||||
Definition step (s : State) (prog : list Instr) : option State :=
|
||||
if halted s then None else
|
||||
if Nat.leb (length prog) (pc s) then
|
||||
Some (mkState (pc s) (stack s) (locals s) true)
|
||||
else
|
||||
let instr := nth (pc s) prog Halt in
|
||||
let stk := stack s in
|
||||
let loc := locals s in
|
||||
let npc := S (pc s) in
|
||||
if s.(halted) then None else
|
||||
match List.nth_error prog s.(pc) with
|
||||
| None => Some (mkState s.(pc) s.(stack) s.(locals) true)
|
||||
| Some instr =>
|
||||
let new_pc := S s.(pc) in
|
||||
let push v := Some (mkState new_pc (v :: s.(stack)) s.(locals) false) in
|
||||
match instr with
|
||||
| PushQ16 x => Some (mkState npc (Vq16 (avm_clamp x) :: stk) loc false)
|
||||
| PushBool b => Some (mkState npc (Vbool b :: stk) loc false)
|
||||
| PushQ0 x => Some (mkState npc (Vq0 (avm_q0_clamp x) :: stk) loc false)
|
||||
| Pop => match stk with
|
||||
| [] => None
|
||||
| _ :: xs => Some (mkState npc xs loc false)
|
||||
| Push_q16 x => push (Vq16 x)
|
||||
| Push_bool x => push (Vbool x)
|
||||
| Pop =>
|
||||
match s.(stack) with
|
||||
| _ :: rest => Some (mkState new_pc rest s.(locals) false)
|
||||
| nil => None
|
||||
end
|
||||
| Dup => match stk with
|
||||
| [] => None
|
||||
| x :: xs => Some (mkState npc (x :: x :: xs) loc false)
|
||||
| Dup =>
|
||||
match s.(stack) with
|
||||
| v :: _ => push v | nil => None
|
||||
end
|
||||
| Swap => match stk with
|
||||
| a :: b :: xs => Some (mkState npc (b :: a :: xs) loc false)
|
||||
| Swap =>
|
||||
match s.(stack) with
|
||||
| a :: b :: rest => Some (mkState new_pc (b :: a :: rest) s.(locals) false)
|
||||
| _ => None
|
||||
end
|
||||
| Load i =>
|
||||
match nth_error loc i with
|
||||
| None => None
|
||||
| Some None => None
|
||||
| Some (Some v) => Some (mkState npc (v :: stk) loc false)
|
||||
match get_local s i with
|
||||
| Some v => push v | None => None
|
||||
end
|
||||
| Store i =>
|
||||
match stk with
|
||||
| [] => None
|
||||
| v :: xs =>
|
||||
if Nat.leb (length loc) i then None
|
||||
else
|
||||
let new_loc := set_nth loc i (Some v) in
|
||||
Some (mkState npc xs new_loc false)
|
||||
match s.(stack) with
|
||||
| v :: rest =>
|
||||
Some (mkState new_pc rest
|
||||
(List.firstn i s.(locals) ++ Some v :: List.skipn (S i) s.(locals)) false)
|
||||
| nil => None
|
||||
end
|
||||
| Jump t => Some (mkState t s.(stack) s.(locals) false)
|
||||
| Jump_if t =>
|
||||
match s.(stack) with
|
||||
| Vbool true :: rest => Some (mkState t rest s.(locals) false)
|
||||
| Vbool false :: rest => Some (mkState new_pc rest s.(locals) false)
|
||||
| _ :: _ => None | nil => None
|
||||
end
|
||||
| Prim_op p =>
|
||||
(match p with
|
||||
| Not =>
|
||||
match s.(stack) with
|
||||
| a :: rest =>
|
||||
match exec_prim p (Some a) None with
|
||||
| Some v => Some (mkState new_pc (v :: rest) s.(locals) false)
|
||||
| None => None
|
||||
end
|
||||
| nil => None
|
||||
end
|
||||
| _ =>
|
||||
match s.(stack) with
|
||||
| a :: b :: rest =>
|
||||
match exec_prim p (Some a) (Some b) with
|
||||
| Some v => Some (mkState new_pc (v :: rest) s.(locals) false)
|
||||
| None => None
|
||||
end
|
||||
| Jump t =>
|
||||
if Nat.leb (length prog) t then None
|
||||
else Some (mkState t stk loc false)
|
||||
| JumpIf t =>
|
||||
match stk with
|
||||
| Vbool true :: xs =>
|
||||
if Nat.leb (length prog) t then None
|
||||
else Some (mkState t xs loc false)
|
||||
| Vbool false :: xs => Some (mkState npc xs loc false)
|
||||
| _ => None
|
||||
end
|
||||
| Primitive p =>
|
||||
let arity := if p = Not then 1 else 2 in
|
||||
match stk with
|
||||
| a :: xs when arity = 1 =>
|
||||
Some (mkState npc (exec_prim p a a :: xs) loc false)
|
||||
| b :: a :: xs when arity = 2 =>
|
||||
Some (mkState npc (exec_prim p a b :: xs) loc false)
|
||||
| _ => None
|
||||
end)
|
||||
| Halt => Some (mkState s.(pc) s.(stack) s.(locals) true)
|
||||
end
|
||||
| Halt => Some (mkState (pc s) stk loc true)
|
||||
end.
|
||||
|
||||
(* ── Run (fuel-bounded) ─────────────────────────────────────────── *)
|
||||
Fixpoint run (s : State) (prog : list Instr) (fuel : nat) : option State :=
|
||||
Fixpoint run (s : State) (prog : list Instr) (fuel : nat) {struct fuel} : option State :=
|
||||
match fuel with
|
||||
| O => Some s
|
||||
| S n =>
|
||||
if halted s then Some s
|
||||
else match step s prog with
|
||||
| None => None
|
||||
| Some s' => run s' prog n
|
||||
| S k =>
|
||||
if s.(halted) then Some s else
|
||||
match step s prog with
|
||||
| None => None | Some s' => run s' prog k
|
||||
end
|
||||
end.
|
||||
|
||||
Lemma step_halted (s : State) (prog : list Instr) (h : s.(halted) = true) :
|
||||
step s prog = None.
|
||||
Proof. unfold step; rewrite h; reflexivity. Qed.
|
||||
|
||||
End AVM.
|
||||
|
|
|
|||
BIN
coq/AVMIsa/avm.vo
Normal file
BIN
coq/AVMIsa/avm.vo
Normal file
Binary file not shown.
0
coq/AVMIsa/avm.vok
Normal file
0
coq/AVMIsa/avm.vok
Normal file
0
coq/AVMIsa/avm.vos
Normal file
0
coq/AVMIsa/avm.vos
Normal file
263
coq/AVMIsa/q16_16.glob
Normal file
263
coq/AVMIsa/q16_16.glob
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
DIGEST 674cb8319be2cff2e3564b20efcaccb5
|
||||
Fq16_16
|
||||
R72:77 Stdlib.ZArith.ZArith <> <> lib
|
||||
R79:81 Stdlib.micromega.Lia <> <> lib
|
||||
prf 91:117 <> le_neg2147483648_2147483647
|
||||
R133:136 Stdlib.ZArith.BinInt <> ::Z_scope:x_'<='_x not
|
||||
prf 175:189 <> le_0_2147483647
|
||||
R195:198 Stdlib.ZArith.BinInt <> ::Z_scope:x_'<='_x not
|
||||
prf 237:254 <> le_neg2147483648_0
|
||||
R270:273 Stdlib.ZArith.BinInt <> ::Z_scope:x_'<='_x not
|
||||
prf 304:327 <> le_2147483647_2147483647
|
||||
R342:345 Stdlib.ZArith.BinInt <> ::Z_scope:x_'<='_x not
|
||||
mod 386:391 <> Q16_16
|
||||
def 430:440 Q16_16 q16_min_raw
|
||||
R444:444 Corelib.Numbers.BinNums <> Z ind
|
||||
def 475:485 Q16_16 q16_max_raw
|
||||
R489:489 Corelib.Numbers.BinNums <> Z ind
|
||||
def 519:527 Q16_16 q16_scale
|
||||
R532:532 Corelib.Numbers.BinNums <> Z ind
|
||||
def 558:565 Q16_16 in_range
|
||||
R572:572 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 568:568 <> x:1
|
||||
R605:608 Corelib.Init.Logic <> ::type_scope:x_'/\'_x not
|
||||
R600:603 Stdlib.ZArith.BinInt <> ::Z_scope:x_'<='_x not
|
||||
R589:599 q16_16 Q16_16 q16_min_raw def
|
||||
R604:604 q16_16 <> x:1 var
|
||||
R610:613 Stdlib.ZArith.BinInt <> ::Z_scope:x_'<='_x not
|
||||
R609:609 q16_16 <> x:1 var
|
||||
R614:624 q16_16 Q16_16 q16_max_raw def
|
||||
def 641:649 Q16_16 clamp_raw
|
||||
R656:656 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 652:652 <> i:2
|
||||
R661:661 Corelib.Numbers.BinNums <> Z ind
|
||||
R673:680 Stdlib.ZArith.ZArith_dec <> Z_lt_dec def
|
||||
R694:694 q16_16 <> i:2 var
|
||||
R682:692 q16_16 Q16_16 q16_max_raw def
|
||||
R725:732 Stdlib.ZArith.ZArith_dec <> Z_lt_dec def
|
||||
R736:746 q16_16 Q16_16 q16_min_raw def
|
||||
R734:734 q16_16 <> i:2 var
|
||||
R774:774 q16_16 <> i:2 var
|
||||
R753:763 q16_16 Q16_16 q16_min_raw def
|
||||
R701:711 q16_16 Q16_16 q16_max_raw def
|
||||
prf 788:800 Q16_16 clamp_bounded
|
||||
R807:807 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 803:803 <> x:3
|
||||
R812:819 q16_16 Q16_16 in_range def
|
||||
R822:830 q16_16 Q16_16 clamp_raw def
|
||||
R832:832 q16_16 <> x:3 var
|
||||
R856:864 q16_16 Q16_16 clamp_raw def
|
||||
R867:874 q16_16 Q16_16 in_range def
|
||||
R887:894 Stdlib.ZArith.ZArith_dec <> Z_lt_dec def
|
||||
R896:906 q16_16 Q16_16 q16_max_raw def
|
||||
R887:894 Stdlib.ZArith.ZArith_dec <> Z_lt_dec def
|
||||
R896:906 q16_16 Q16_16 q16_max_raw def
|
||||
R936:946 q16_16 Q16_16 q16_min_raw def
|
||||
R949:959 q16_16 Q16_16 q16_max_raw def
|
||||
R976:1002 q16_16 <> le_neg2147483648_2147483647 thm
|
||||
R1012:1020 Stdlib.ZArith.BinInt Z le_refl thm
|
||||
R976:1002 q16_16 <> le_neg2147483648_2147483647 thm
|
||||
R1012:1020 Stdlib.ZArith.BinInt Z le_refl thm
|
||||
R1036:1043 Stdlib.ZArith.ZArith_dec <> Z_lt_dec def
|
||||
R1047:1057 q16_16 Q16_16 q16_min_raw def
|
||||
R1036:1043 Stdlib.ZArith.ZArith_dec <> Z_lt_dec def
|
||||
R1047:1057 q16_16 Q16_16 q16_min_raw def
|
||||
R1087:1097 q16_16 Q16_16 q16_min_raw def
|
||||
R1100:1110 q16_16 Q16_16 q16_max_raw def
|
||||
R1127:1135 Stdlib.ZArith.BinInt Z le_refl thm
|
||||
R1145:1171 q16_16 <> le_neg2147483648_2147483647 thm
|
||||
R1127:1135 Stdlib.ZArith.BinInt Z le_refl thm
|
||||
R1145:1171 q16_16 <> le_neg2147483648_2147483647 thm
|
||||
R1196:1203 Stdlib.ZArith.BinInt Z nlt_ge thm
|
||||
R1196:1203 Stdlib.ZArith.BinInt Z nlt_ge thm
|
||||
R1196:1203 Stdlib.ZArith.BinInt Z nlt_ge thm
|
||||
prf 1236:1251 Q16_16 clamp_idempotent
|
||||
R1258:1258 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 1254:1254 <> x:4
|
||||
R1266:1273 q16_16 Q16_16 in_range def
|
||||
R1275:1275 q16_16 <> x:4 var
|
||||
binder 1262:1262 <> h:5
|
||||
R1291:1293 Corelib.Init.Logic <> ::type_scope:x_'='_x not
|
||||
R1280:1288 q16_16 Q16_16 clamp_raw def
|
||||
R1290:1290 q16_16 <> x:4 var
|
||||
R1294:1294 q16_16 <> x:4 var
|
||||
R1346:1354 q16_16 Q16_16 clamp_raw def
|
||||
R1367:1374 Stdlib.ZArith.ZArith_dec <> Z_lt_dec def
|
||||
R1376:1386 q16_16 Q16_16 q16_max_raw def
|
||||
R1421:1430 Stdlib.ZArith.Zorder <> Zlt_not_le thm
|
||||
R1367:1374 Stdlib.ZArith.ZArith_dec <> Z_lt_dec def
|
||||
R1376:1386 q16_16 Q16_16 q16_max_raw def
|
||||
R1421:1430 Stdlib.ZArith.Zorder <> Zlt_not_le thm
|
||||
R1459:1466 Stdlib.ZArith.ZArith_dec <> Z_lt_dec def
|
||||
R1470:1480 q16_16 Q16_16 q16_min_raw def
|
||||
R1513:1522 Stdlib.ZArith.Zorder <> Zlt_not_le thm
|
||||
R1459:1466 Stdlib.ZArith.ZArith_dec <> Z_lt_dec def
|
||||
R1470:1480 q16_16 Q16_16 q16_min_raw def
|
||||
R1513:1522 Stdlib.ZArith.Zorder <> Zlt_not_le thm
|
||||
def 1579:1582 Q16_16 zero
|
||||
R1586:1586 Corelib.Numbers.BinNums <> Z ind
|
||||
def 1607:1609 Q16_16 one
|
||||
R1613:1613 Corelib.Numbers.BinNums <> Z ind
|
||||
def 1638:1644 Q16_16 epsilon
|
||||
R1648:1648 Corelib.Numbers.BinNums <> Z ind
|
||||
def 1669:1672 Q16_16 half
|
||||
R1676:1676 Corelib.Numbers.BinNums <> Z ind
|
||||
def 1701:1704 Q16_16 pct1
|
||||
R1710:1710 Corelib.Numbers.BinNums <> Z ind
|
||||
def 1733:1737 Q16_16 pct70
|
||||
R1742:1742 Corelib.Numbers.BinNums <> Z ind
|
||||
def 1767:1771 Q16_16 pct30
|
||||
R1776:1776 Corelib.Numbers.BinNums <> Z ind
|
||||
def 1801:1805 Q16_16 one50
|
||||
R1810:1810 Corelib.Numbers.BinNums <> Z ind
|
||||
def 1836:1838 Q16_16 add
|
||||
R1847:1847 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 1841:1841 <> a:6
|
||||
binder 1843:1843 <> b:7
|
||||
R1852:1852 Corelib.Numbers.BinNums <> Z ind
|
||||
R1857:1865 q16_16 Q16_16 clamp_raw def
|
||||
R1869:1871 Stdlib.ZArith.BinInt <> ::Z_scope:x_'+'_x not
|
||||
R1868:1868 q16_16 <> a:6 var
|
||||
R1872:1872 q16_16 <> b:7 var
|
||||
def 1889:1891 Q16_16 sub
|
||||
R1900:1900 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 1894:1894 <> a:8
|
||||
binder 1896:1896 <> b:9
|
||||
R1905:1905 Corelib.Numbers.BinNums <> Z ind
|
||||
R1910:1918 q16_16 Q16_16 clamp_raw def
|
||||
R1922:1924 Stdlib.ZArith.BinInt <> ::Z_scope:x_'-'_x not
|
||||
R1921:1921 q16_16 <> a:8 var
|
||||
R1925:1925 q16_16 <> b:9 var
|
||||
def 1942:1944 Q16_16 neg
|
||||
R1951:1951 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 1947:1947 <> a:10
|
||||
R1956:1956 Corelib.Numbers.BinNums <> Z ind
|
||||
R1961:1969 q16_16 Q16_16 clamp_raw def
|
||||
R1972:1972 Stdlib.ZArith.BinInt <> ::Z_scope:'-'_x not
|
||||
R1973:1973 q16_16 <> a:10 var
|
||||
def 1990:1992 Q16_16 mul
|
||||
R2001:2001 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 1995:1995 <> a:11
|
||||
binder 1997:1997 <> b:12
|
||||
R2006:2006 Corelib.Numbers.BinNums <> Z ind
|
||||
R2011:2019 q16_16 Q16_16 clamp_raw def
|
||||
R2022:2026 Stdlib.ZArith.BinInt Z div def
|
||||
R2030:2032 Stdlib.ZArith.BinInt <> ::Z_scope:x_'*'_x not
|
||||
R2029:2029 q16_16 <> a:11 var
|
||||
R2033:2033 q16_16 <> b:12 var
|
||||
R2036:2044 q16_16 Q16_16 q16_scale def
|
||||
def 2061:2063 Q16_16 div
|
||||
R2072:2072 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 2066:2066 <> a:13
|
||||
binder 2068:2068 <> b:14
|
||||
R2077:2077 Corelib.Numbers.BinNums <> Z ind
|
||||
R2089:2096 Stdlib.ZArith.BinInt Z eq_dec def
|
||||
R2098:2098 q16_16 <> b:14 var
|
||||
R2117:2125 q16_16 Q16_16 clamp_raw def
|
||||
R2128:2132 Stdlib.ZArith.BinInt Z div def
|
||||
R2136:2138 Stdlib.ZArith.BinInt <> ::Z_scope:x_'*'_x not
|
||||
R2135:2135 q16_16 <> a:13 var
|
||||
R2139:2147 q16_16 Q16_16 q16_scale def
|
||||
R2150:2150 q16_16 <> b:14 var
|
||||
R2107:2110 q16_16 Q16_16 zero def
|
||||
prf 2165:2172 Q16_16 add_comm
|
||||
R2181:2181 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 2175:2175 <> a:15
|
||||
binder 2177:2177 <> b:16
|
||||
R2193:2195 Corelib.Init.Logic <> ::type_scope:x_'='_x not
|
||||
R2186:2188 q16_16 Q16_16 add def
|
||||
R2190:2190 q16_16 <> a:15 var
|
||||
R2192:2192 q16_16 <> b:16 var
|
||||
R2196:2198 q16_16 Q16_16 add def
|
||||
R2200:2200 q16_16 <> b:16 var
|
||||
R2202:2202 q16_16 <> a:15 var
|
||||
R2221:2223 q16_16 Q16_16 add def
|
||||
R2234:2243 Stdlib.ZArith.BinInt Z add_comm thm
|
||||
R2234:2243 Stdlib.ZArith.BinInt Z add_comm thm
|
||||
R2234:2243 Stdlib.ZArith.BinInt Z add_comm thm
|
||||
prf 2275:2286 Q16_16 add_in_range
|
||||
R2295:2295 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 2289:2289 <> a:17
|
||||
binder 2291:2291 <> b:18
|
||||
R2304:2311 q16_16 Q16_16 in_range def
|
||||
R2313:2313 q16_16 <> a:17 var
|
||||
binder 2299:2300 <> ha:19
|
||||
R2322:2329 q16_16 Q16_16 in_range def
|
||||
R2331:2331 q16_16 <> b:18 var
|
||||
binder 2317:2318 <> hb:20
|
||||
R2346:2353 q16_16 Q16_16 in_range def
|
||||
R2357:2359 Stdlib.ZArith.BinInt <> ::Z_scope:x_'+'_x not
|
||||
R2356:2356 q16_16 <> a:17 var
|
||||
R2360:2360 q16_16 <> b:18 var
|
||||
binder 2339:2342 <> hsum:21
|
||||
R2373:2375 Corelib.Init.Logic <> ::type_scope:x_'='_x not
|
||||
R2366:2368 q16_16 Q16_16 add def
|
||||
R2370:2370 q16_16 <> a:17 var
|
||||
R2372:2372 q16_16 <> b:18 var
|
||||
R2377:2379 Stdlib.ZArith.BinInt <> ::Z_scope:x_'+'_x not
|
||||
R2376:2376 q16_16 <> a:17 var
|
||||
R2380:2380 q16_16 <> b:18 var
|
||||
R2403:2405 q16_16 Q16_16 add def
|
||||
R2416:2431 q16_16 Q16_16 clamp_idempotent thm
|
||||
R2416:2431 q16_16 Q16_16 clamp_idempotent thm
|
||||
R2416:2431 q16_16 Q16_16 clamp_idempotent thm
|
||||
R2416:2431 q16_16 Q16_16 clamp_idempotent thm
|
||||
prf 2461:2468 Q16_16 sub_self
|
||||
R2475:2475 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 2471:2471 <> a:22
|
||||
R2484:2491 q16_16 Q16_16 in_range def
|
||||
R2493:2493 q16_16 <> a:22 var
|
||||
binder 2479:2480 <> ha:23
|
||||
R2505:2507 Corelib.Init.Logic <> ::type_scope:x_'='_x not
|
||||
R2498:2500 q16_16 Q16_16 sub def
|
||||
R2502:2502 q16_16 <> a:22 var
|
||||
R2504:2504 q16_16 <> a:22 var
|
||||
R2508:2511 q16_16 Q16_16 zero def
|
||||
R2534:2536 q16_16 Q16_16 sub def
|
||||
R2539:2542 q16_16 Q16_16 zero def
|
||||
R2553:2562 Stdlib.ZArith.BinInt Z sub_diag thm
|
||||
R2553:2562 Stdlib.ZArith.BinInt Z sub_diag thm
|
||||
R2553:2562 Stdlib.ZArith.BinInt Z sub_diag thm
|
||||
R2575:2590 q16_16 Q16_16 clamp_idempotent thm
|
||||
R2600:2607 q16_16 Q16_16 in_range def
|
||||
R2617:2627 q16_16 Q16_16 q16_min_raw def
|
||||
R2630:2640 q16_16 Q16_16 q16_max_raw def
|
||||
R2575:2590 q16_16 Q16_16 clamp_idempotent thm
|
||||
R2661:2678 q16_16 <> le_neg2147483648_0 thm
|
||||
R2688:2702 q16_16 <> le_0_2147483647 thm
|
||||
R2661:2678 q16_16 <> le_neg2147483648_0 thm
|
||||
R2688:2702 q16_16 <> le_0_2147483647 thm
|
||||
prf 2724:2731 Q16_16 mul_comm
|
||||
R2740:2740 Corelib.Numbers.BinNums <> Z ind
|
||||
binder 2734:2734 <> a:24
|
||||
binder 2736:2736 <> b:25
|
||||
R2752:2754 Corelib.Init.Logic <> ::type_scope:x_'='_x not
|
||||
R2745:2747 q16_16 Q16_16 mul def
|
||||
R2749:2749 q16_16 <> a:24 var
|
||||
R2751:2751 q16_16 <> b:25 var
|
||||
R2755:2757 q16_16 Q16_16 mul def
|
||||
R2759:2759 q16_16 <> b:25 var
|
||||
R2761:2761 q16_16 <> a:24 var
|
||||
R2780:2782 q16_16 Q16_16 mul def
|
||||
R2793:2802 Stdlib.ZArith.BinInt Z mul_comm thm
|
||||
R2793:2802 Stdlib.ZArith.BinInt Z mul_comm thm
|
||||
R2793:2802 Stdlib.ZArith.BinInt Z mul_comm thm
|
||||
prf 2834:2846 Q16_16 in_range_zero
|
||||
R2850:2857 q16_16 Q16_16 in_range def
|
||||
R2878:2885 q16_16 Q16_16 in_range def
|
||||
R2888:2898 q16_16 Q16_16 q16_min_raw def
|
||||
R2901:2911 q16_16 Q16_16 q16_max_raw def
|
||||
R2928:2945 q16_16 <> le_neg2147483648_0 thm
|
||||
R2955:2969 q16_16 <> le_0_2147483647 thm
|
||||
R2928:2945 q16_16 <> le_neg2147483648_0 thm
|
||||
R2955:2969 q16_16 <> le_0_2147483647 thm
|
||||
prf 2989:3000 Q16_16 in_range_one
|
||||
R3004:3011 q16_16 Q16_16 in_range def
|
||||
R3032:3039 q16_16 Q16_16 in_range def
|
||||
R3042:3052 q16_16 Q16_16 q16_min_raw def
|
||||
R3055:3065 q16_16 Q16_16 q16_max_raw def
|
||||
R3082:3099 q16_16 <> le_neg2147483648_0 thm
|
||||
R3109:3123 q16_16 <> le_0_2147483647 thm
|
||||
R3082:3099 q16_16 <> le_neg2147483648_0 thm
|
||||
R3109:3123 q16_16 <> le_0_2147483647 thm
|
||||
R3137:3142 q16_16 Q16_16 <> mod
|
||||
89
coq/AVMIsa/q16_16.v
Normal file
89
coq/AVMIsa/q16_16.v
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
(* Coq Formalization of Q16_16 Fixed-Point Arithmetic *)
|
||||
Require Import ZArith Lia.
|
||||
|
||||
Lemma le_neg2147483648_2147483647 : (-2147483648 <= 2147483647)%Z.
|
||||
Proof. lia. Qed.
|
||||
Lemma le_0_2147483647 : (0 <= 2147483647)%Z.
|
||||
Proof. lia. Qed.
|
||||
Lemma le_neg2147483648_0 : (-2147483648 <= 0)%Z.
|
||||
Proof. lia. Qed.
|
||||
|
||||
Lemma le_2147483647_2147483647 : (2147483647 <= 2147483647)%Z.
|
||||
Proof. lia. Qed.
|
||||
|
||||
Module Q16_16.
|
||||
Open Scope Z_scope.
|
||||
|
||||
Definition q16_min_raw : Z := -2147483648.
|
||||
Definition q16_max_raw : Z := 2147483647.
|
||||
Definition q16_scale : Z := 65536.
|
||||
|
||||
Definition in_range (x : Z) : Prop :=
|
||||
q16_min_raw <= x /\ x <= q16_max_raw.
|
||||
|
||||
Definition clamp_raw (i : Z) : Z :=
|
||||
if Z_lt_dec q16_max_raw i then q16_max_raw
|
||||
else if Z_lt_dec i q16_min_raw then q16_min_raw
|
||||
else i.
|
||||
|
||||
Theorem clamp_bounded (x : Z) : in_range (clamp_raw x).
|
||||
Proof.
|
||||
unfold clamp_raw, in_range.
|
||||
case (Z_lt_dec q16_max_raw x); intros H1.
|
||||
- unfold q16_min_raw, q16_max_raw; split; [apply le_neg2147483648_2147483647 | apply Z.le_refl].
|
||||
- case (Z_lt_dec x q16_min_raw); intros H2.
|
||||
+ unfold q16_min_raw, q16_max_raw; split; [apply Z.le_refl | apply le_neg2147483648_2147483647].
|
||||
+ split; apply Z.nlt_ge; assumption.
|
||||
Qed.
|
||||
|
||||
Theorem clamp_idempotent (x : Z) (h : in_range x) : clamp_raw x = x.
|
||||
Proof.
|
||||
destruct h as [Hlo Hhi].
|
||||
unfold clamp_raw.
|
||||
case (Z_lt_dec q16_max_raw x); intros Hgt; [exfalso; exact (Zlt_not_le _ _ Hgt Hhi) |].
|
||||
case (Z_lt_dec x q16_min_raw); intros Hlt; [exfalso; exact (Zlt_not_le _ _ Hlt Hlo) |].
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Definition zero : Z := 0.
|
||||
Definition one : Z := 65536.
|
||||
Definition epsilon : Z := 1.
|
||||
Definition half : Z := 32768.
|
||||
Definition pct1 : Z := 655.
|
||||
Definition pct70 : Z := 45875.
|
||||
Definition pct30 : Z := 19661.
|
||||
Definition one50 : Z := 98304.
|
||||
|
||||
Definition add (a b : Z) : Z := clamp_raw (a + b).
|
||||
Definition sub (a b : Z) : Z := clamp_raw (a - b).
|
||||
Definition neg (a : Z) : Z := clamp_raw (-a).
|
||||
Definition mul (a b : Z) : Z := clamp_raw (Z.div (a * b) q16_scale).
|
||||
Definition div (a b : Z) : Z :=
|
||||
if Z.eq_dec b 0 then zero else clamp_raw (Z.div (a * q16_scale) b).
|
||||
|
||||
Theorem add_comm (a b : Z) : add a b = add b a.
|
||||
Proof. unfold add; rewrite Z.add_comm; reflexivity. Qed.
|
||||
|
||||
Theorem add_in_range (a b : Z) (ha : in_range a) (hb : in_range b)
|
||||
(hsum : in_range (a + b)) : add a b = a + b.
|
||||
Proof.
|
||||
unfold add; rewrite clamp_idempotent; trivial.
|
||||
Qed.
|
||||
|
||||
Theorem sub_self (a : Z) (ha : in_range a) : sub a a = zero.
|
||||
Proof.
|
||||
unfold sub, zero; rewrite Z.sub_diag.
|
||||
apply clamp_idempotent; unfold in_range; unfold q16_min_raw, q16_max_raw.
|
||||
split; [apply le_neg2147483648_0 | apply le_0_2147483647].
|
||||
Qed.
|
||||
|
||||
Theorem mul_comm (a b : Z) : mul a b = mul b a.
|
||||
Proof. unfold mul; rewrite Z.mul_comm; reflexivity. Qed.
|
||||
|
||||
Theorem in_range_zero : in_range 0.
|
||||
Proof. unfold in_range, q16_min_raw, q16_max_raw. split; [apply le_neg2147483648_0 | apply le_0_2147483647]. Qed.
|
||||
|
||||
Theorem in_range_one : in_range 1.
|
||||
Proof. unfold in_range, q16_min_raw, q16_max_raw. split; [apply le_neg2147483648_0 | apply le_0_2147483647]. Qed.
|
||||
|
||||
End Q16_16.
|
||||
BIN
coq/AVMIsa/q16_16.vo
Normal file
BIN
coq/AVMIsa/q16_16.vo
Normal file
Binary file not shown.
0
coq/AVMIsa/q16_16.vok
Normal file
0
coq/AVMIsa/q16_16.vok
Normal file
0
coq/AVMIsa/q16_16.vos
Normal file
0
coq/AVMIsa/q16_16.vos
Normal file
144
cpp/AVMIsa/avm.hpp
Normal file
144
cpp/AVMIsa/avm.hpp
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
// AVM ISA v1 — C++ Port (Strict Functional Execution)
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
#include <stdexcept>
|
||||
#include <functional>
|
||||
|
||||
constexpr int32_t Q16_SCALE = 65536;
|
||||
|
||||
inline int32_t q16_mul(int32_t a, int32_t b) {
|
||||
return static_cast<int32_t>(
|
||||
(static_cast<int64_t>(a) * static_cast<int64_t>(b)) / Q16_SCALE);
|
||||
}
|
||||
inline int32_t q16_div(int32_t a, int32_t b) {
|
||||
if (b == 0) throw std::runtime_error("div by zero");
|
||||
return static_cast<int32_t>(
|
||||
(static_cast<int64_t>(a) * Q16_SCALE) / b);
|
||||
}
|
||||
|
||||
// ── Value ─────────────────────────────────────────
|
||||
struct AvmVal {
|
||||
enum Ty { Q0_16, Q16_16, Bool };
|
||||
Ty ty;
|
||||
int32_t raw;
|
||||
AvmVal(Ty t, int32_t r) : ty(t), raw(r) {}
|
||||
static AvmVal q16(int32_t x) { return {Q16_16, x}; }
|
||||
static AvmVal q0(int32_t x) {
|
||||
if (x < -32767) x = -32767;
|
||||
if (x > 32767) x = 32767;
|
||||
return {Q0_16, x};
|
||||
}
|
||||
static AvmVal boolean(bool x) { return {Bool, x ? 1 : 0}; }
|
||||
};
|
||||
|
||||
// ── Primitives ─────────────────────────────────────
|
||||
enum class Prim : int32_t {
|
||||
AddSatQ0, SubSatQ0, AddSatQ16, SubSatQ16, MulSatQ16, DivSatQ16,
|
||||
LtQ16, EqQ16, And, Or, Not
|
||||
};
|
||||
|
||||
AvmVal exec_prim(Prim op, const AvmVal& a, const std::optional<AvmVal>& b) {
|
||||
auto bv = [&]() -> const AvmVal& { return b.value(); };
|
||||
switch (op) {
|
||||
case Prim::AddSatQ16: return AvmVal::q16(a.raw + bv().raw);
|
||||
case Prim::SubSatQ16: return AvmVal::q16(a.raw - bv().raw);
|
||||
case Prim::MulSatQ16: return AvmVal::q16(q16_mul(a.raw, bv().raw));
|
||||
case Prim::DivSatQ16: return AvmVal::q16(q16_div(a.raw, bv().raw));
|
||||
case Prim::LtQ16: return AvmVal::boolean(a.raw < bv().raw);
|
||||
case Prim::EqQ16: return AvmVal::boolean(a.raw == bv().raw);
|
||||
case Prim::And: return AvmVal::boolean(a.raw && bv().raw);
|
||||
case Prim::Or: return AvmVal::boolean(a.raw || bv().raw);
|
||||
case Prim::Not: return AvmVal::boolean(!a.raw);
|
||||
default: throw std::runtime_error("unknown prim");
|
||||
}
|
||||
}
|
||||
|
||||
// ── Instruction ────────────────────────────────────
|
||||
enum class InstrOp : int8_t {
|
||||
PushQ16, PushBool, Pop, Dup, Swap, Load, Store, Jump, JumpIf, Prim, Halt
|
||||
};
|
||||
|
||||
struct Instr {
|
||||
InstrOp op;
|
||||
int32_t arg;
|
||||
bool arg2{false};
|
||||
};
|
||||
|
||||
inline Instr push_q16(int32_t x) { return {InstrOp::PushQ16, x, false}; }
|
||||
inline Instr push_bool(bool x) { return {InstrOp::PushBool, static_cast<int32_t>(x), true}; }
|
||||
inline Instr pop() { return {InstrOp::Pop, 0, false}; }
|
||||
inline Instr dup() { return {InstrOp::Dup, 0, false}; }
|
||||
inline Instr swap() { return {InstrOp::Swap, 0, false}; }
|
||||
inline Instr load(int i) { return {InstrOp::Load, i, false}; }
|
||||
inline Instr store(int i) { return {InstrOp::Store, i, false}; }
|
||||
inline Instr jump(int t) { return {InstrOp::Jump, t, false}; }
|
||||
inline Instr jump_if(int t) { return {InstrOp::JumpIf, t, false}; }
|
||||
inline Instr prim(Prim p) { return {InstrOp::Prim, static_cast<int32_t>(p), false}; }
|
||||
inline Instr halt() { return {InstrOp::Halt, 0, false}; }
|
||||
|
||||
// ── State ──────────────────────────────────────────
|
||||
struct State {
|
||||
int pc{0};
|
||||
std::vector<AvmVal> stack;
|
||||
std::vector<std::optional<AvmVal>> locals;
|
||||
bool halted{false};
|
||||
|
||||
State() : pc(0), locals(16, std::nullopt) {}
|
||||
State(int pc_, std::vector<AvmVal> stack_, std::vector<std::optional<AvmVal>> locals_, bool halted_)
|
||||
: pc(pc_), stack(std::move(stack_)), locals(std::move(locals_)), halted(halted_) {}
|
||||
};
|
||||
|
||||
// ── Step ───────────────────────────────────────────
|
||||
State step(const State& s, const std::vector<Instr>& prog) {
|
||||
if (s.halted) throw std::runtime_error("halted");
|
||||
if (s.pc < 0 || s.pc >= (int)prog.size())
|
||||
return State{};
|
||||
|
||||
auto instr = prog[s.pc];
|
||||
State ns{s.pc + 1, s.stack, s.locals, false};
|
||||
auto& st = ns.stack;
|
||||
|
||||
switch (instr.op) {
|
||||
case InstrOp::PushQ16: st.push_back(AvmVal::q16(instr.arg)); break;
|
||||
case InstrOp::PushBool: st.push_back(AvmVal::boolean(instr.arg)); break;
|
||||
case InstrOp::Pop: st.pop_back(); break;
|
||||
case InstrOp::Dup: st.push_back(st.back()); break;
|
||||
case InstrOp::Swap: std::swap(st[st.size()-2], st[st.size()-1]); break;
|
||||
case InstrOp::Load: {
|
||||
auto v = ns.locals[instr.arg];
|
||||
if (!v.has_value()) throw std::runtime_error("missing local");
|
||||
st.push_back(v.value());
|
||||
break;
|
||||
}
|
||||
case InstrOp::Store: {
|
||||
ns.locals[instr.arg] = st.back(); st.pop_back();
|
||||
break;
|
||||
}
|
||||
case InstrOp::Jump: ns.pc = instr.arg; break;
|
||||
case InstrOp::JumpIf: {
|
||||
if (st.back().raw) ns.pc = instr.arg;
|
||||
st.pop_back();
|
||||
break;
|
||||
}
|
||||
case InstrOp::Prim: {
|
||||
auto p = static_cast<Prim>(instr.arg);
|
||||
int arity = (p == Prim::Not) ? 1 : 2;
|
||||
std::optional<AvmVal> b;
|
||||
if (arity == 2) { b = st.back(); st.pop_back(); }
|
||||
auto a = st.back(); st.pop_back();
|
||||
st.push_back(exec_prim(p, a, b));
|
||||
break;
|
||||
}
|
||||
case InstrOp::Halt: ns.halted = true; break;
|
||||
}
|
||||
return ns;
|
||||
}
|
||||
|
||||
State run(const State& init, const std::vector<Instr>& prog, int fuel) {
|
||||
State s = init;
|
||||
for (int i = 0; i < fuel && !s.halted; i++)
|
||||
s = step(s, prog);
|
||||
return s;
|
||||
}
|
||||
|
|
@ -10,12 +10,12 @@ test harness.
|
|||
|---|----------|-----|----------|-------|-------------------|--------|
|
||||
| 1 | Lean | `lean --server` | `formal/SilverSight/AVMIsa/` | `E2E.lean` | ✅ | **Reference** |
|
||||
| 2 | Rust | `rust-analyzer` | `rust/src/avm/mod.rs` | `test_add_q16` | ✅ | ✅ |
|
||||
| 3 | Python | `pyright` | `python/avm.py` | ❌ | ❌ | 🔄 |
|
||||
| 3 | Python | `pyright` | `python/avm.py` | `test_avm_python.py` | ❌ | ✅ |
|
||||
| 4 | Coq | `coq-lsp` | `coq/AVMIsa/avm.v` | ❌ | ❌ | 🔄 |
|
||||
| 5 | R | — | `r/AVMIsa/avm.r` | `test_avm.r` | ✅ | ✅ |
|
||||
| 6 | Julia | — | `julia/AVMIsa/avm.jl` | `test_avm.jl` | ✅ | ✅ |
|
||||
| 7 | Scala | `metals` | `scala/avm.scala` | ❌ | ❌ | 🔄 |
|
||||
| 8 | Go | — | `go/avm.go` | ❌ | ❌ | 🔄 |
|
||||
| 8 | Go | — | `go/avm.go` | `go/avm_test.go` | ❌ | 🔄 |
|
||||
| 9 | C | `clangd` | `c/avm.c` | ❌ | ❌ | 🔄 |
|
||||
| 10 | C++ | `clangd` | `cpp/avm.hpp` | ❌ | ❌ | 🔄 |
|
||||
| 11 | Fortran | `fortls` | `fortran/avm.f90` | ❌ | ❌ | 🔄 |
|
||||
|
|
|
|||
166
fortran/AVMIsa/avm.f90
Normal file
166
fortran/AVMIsa/avm.f90
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
! AVM ISA v1 — Fortran Port (Strict Functional Execution)
|
||||
module avm
|
||||
implicit none
|
||||
|
||||
integer, parameter :: Q16_SCALE = 65536
|
||||
integer, parameter :: MAX_STACK = 1024
|
||||
integer, parameter :: MAX_LOCALS = 16
|
||||
integer, parameter :: MAX_PROG = 256
|
||||
|
||||
! Value type codes
|
||||
integer, parameter :: VAL_Q16 = 0, VAL_BOOL = 1
|
||||
|
||||
type :: AvmVal
|
||||
integer :: ty = VAL_Q16
|
||||
integer :: val = 0
|
||||
end type
|
||||
|
||||
! Primitive codes
|
||||
integer, parameter :: PRIM_ADD = 0, PRIM_SUB = 1, PRIM_MUL = 2, PRIM_DIV = 3
|
||||
integer, parameter :: PRIM_LT = 4, PRIM_EQ = 5, PRIM_AND = 6, PRIM_OR = 7, PRIM_NOT = 8
|
||||
|
||||
! Instruction opcodes
|
||||
integer, parameter :: I_PUSH_Q16 = 0, I_PUSH_BOOL = 1, I_POP = 2, I_DUP = 3
|
||||
integer, parameter :: I_SWAP = 4, I_LOAD = 5, I_STORE = 6, I_JUMP = 7
|
||||
integer, parameter :: I_JUMP_IF = 8, I_PRIM = 9, I_HALT = 10
|
||||
|
||||
type :: Instr
|
||||
integer :: op = 0
|
||||
integer :: arg = 0
|
||||
end type
|
||||
|
||||
type :: State
|
||||
integer :: pc = 0
|
||||
type(AvmVal) :: stack(MAX_STACK)
|
||||
integer :: sp = 0 ! stack pointer
|
||||
type(AvmVal) :: locals(MAX_LOCALS)
|
||||
logical :: halted = .false.
|
||||
end type
|
||||
|
||||
contains
|
||||
|
||||
function q16_mul(a, b) result(r)
|
||||
integer, intent(in) :: a, b
|
||||
integer :: r
|
||||
r = int((int(a, 8) * int(b, 8)) / Q16_SCALE)
|
||||
end function
|
||||
|
||||
function q16_div(a, b) result(r)
|
||||
integer, intent(in) :: a, b
|
||||
integer :: r
|
||||
if (b == 0) then
|
||||
r = 2147483647
|
||||
return
|
||||
end if
|
||||
r = int((int(a, 8) * Q16_SCALE) / int(b, 8))
|
||||
end function
|
||||
|
||||
function make_q16(x) result(v)
|
||||
integer, intent(in) :: x
|
||||
type(AvmVal) :: v
|
||||
v%ty = VAL_Q16; v%val = x
|
||||
end function
|
||||
|
||||
function make_bool(x) result(v)
|
||||
logical, intent(in) :: x
|
||||
type(AvmVal) :: v
|
||||
v%ty = VAL_BOOL
|
||||
if (x) then; v%val = 1; else; v%val = 0; end if
|
||||
end function
|
||||
|
||||
function make_instr(op, arg) result(i)
|
||||
integer, intent(in) :: op, arg
|
||||
type(Instr) :: i
|
||||
i%op = op; i%arg = arg
|
||||
end function
|
||||
|
||||
subroutine push(s, v)
|
||||
type(State), intent(inout) :: s
|
||||
type(AvmVal), intent(in) :: v
|
||||
s%sp = s%sp + 1
|
||||
s%stack(s%sp) = v
|
||||
end subroutine
|
||||
|
||||
function pop(s) result(v)
|
||||
type(State), intent(inout) :: s
|
||||
type(AvmVal) :: v
|
||||
v = s%stack(s%sp)
|
||||
s%sp = s%sp - 1
|
||||
end function
|
||||
|
||||
function step(state, prog, prog_len) result(ns)
|
||||
type(State), intent(in) :: state
|
||||
type(Instr), intent(in) :: prog(MAX_PROG)
|
||||
integer, intent(in) :: prog_len
|
||||
type(State) :: ns
|
||||
type(AvmVal) :: a, b, result
|
||||
integer :: arity
|
||||
|
||||
ns = state
|
||||
if (ns%halted) return
|
||||
if (ns%pc < 0 .or. ns%pc >= prog_len) then
|
||||
ns%halted = .true.; return
|
||||
end if
|
||||
|
||||
select case (prog(ns%pc + 1)%op) ! +1 for 1-indexed
|
||||
case (I_PUSH_Q16)
|
||||
call push(ns, make_q16(prog(ns%pc + 1)%arg))
|
||||
case (I_PUSH_BOOL)
|
||||
call push(ns, make_bool(prog(ns%pc + 1)%arg /= 0))
|
||||
case (I_POP)
|
||||
a = pop(ns)
|
||||
case (I_DUP)
|
||||
a = ns%stack(ns%sp)
|
||||
call push(ns, a)
|
||||
case (I_SWAP)
|
||||
a = pop(ns); b = pop(ns)
|
||||
call push(ns, a); call push(ns, b)
|
||||
case (I_LOAD)
|
||||
call push(ns, ns%locals(prog(ns%pc + 1)%arg + 1))
|
||||
case (I_STORE)
|
||||
ns%locals(prog(ns%pc + 1)%arg + 1) = pop(ns)
|
||||
case (I_JUMP)
|
||||
ns%pc = prog(ns%pc + 1)%arg - 1; return
|
||||
case (I_JUMP_IF)
|
||||
a = pop(ns)
|
||||
if (a%val /= 0) ns%pc = prog(ns%pc + 1)%arg - 1
|
||||
case (I_PRIM)
|
||||
arity = 2
|
||||
if (prog(ns%pc + 1)%arg == PRIM_NOT) arity = 1
|
||||
if (arity == 2) b = pop(ns)
|
||||
a = pop(ns)
|
||||
select case (prog(ns%pc + 1)%arg)
|
||||
case (PRIM_ADD); result = make_q16(a%val + b%val)
|
||||
case (PRIM_SUB); result = make_q16(a%val - b%val)
|
||||
case (PRIM_MUL); result = make_q16(q16_mul(a%val, b%val))
|
||||
case (PRIM_DIV); result = make_q16(q16_div(a%val, b%val))
|
||||
case (PRIM_LT); result = make_bool(a%val < b%val)
|
||||
case (PRIM_EQ); result = make_bool(a%val == b%val)
|
||||
case (PRIM_AND); result = make_bool(a%val /= 0 .and. b%val /= 0)
|
||||
case (PRIM_OR); result = make_bool(a%val /= 0 .or. b%val /= 0)
|
||||
case (PRIM_NOT); result = make_bool(a%val == 0)
|
||||
end select
|
||||
call push(ns, result)
|
||||
case (I_HALT)
|
||||
ns%halted = .true.
|
||||
end select
|
||||
ns%pc = ns%pc + 1
|
||||
end function
|
||||
|
||||
subroutine run(init, prog, prog_len, fuel, out_state)
|
||||
type(State), intent(in) :: init
|
||||
type(Instr), intent(in) :: prog(MAX_PROG)
|
||||
integer, intent(in) :: prog_len, fuel
|
||||
type(State), intent(out) :: out_state
|
||||
type(State) :: s
|
||||
integer :: i
|
||||
|
||||
s = init
|
||||
do i = 1, fuel
|
||||
if (s%halted) exit
|
||||
s = step(s, prog, prog_len)
|
||||
end do
|
||||
out_state = s
|
||||
end subroutine
|
||||
|
||||
end module
|
||||
138
go/AVMIsa/avm.go
Normal file
138
go/AVMIsa/avm.go
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
// AVM ISA v1 — Go Port (Strict Functional Execution)
|
||||
package avm
|
||||
|
||||
import "errors"
|
||||
|
||||
const Q16Scale = 65536
|
||||
|
||||
func q16Mul(a, b int32) int32 {
|
||||
return int32((int64(a) * int64(b)) / Q16Scale)
|
||||
}
|
||||
func q16Div(a, b int32) (int32, error) {
|
||||
if b == 0 { return 0, errors.New("div by zero") }
|
||||
return int32((int64(a) * Q16Scale) / b), nil
|
||||
}
|
||||
|
||||
// ── Value ─────────────────────────────────────────
|
||||
type ValType int
|
||||
const (
|
||||
ValQ0 ValType = iota
|
||||
ValQ16
|
||||
ValBool
|
||||
)
|
||||
type AvmVal struct { Ty ValType; Raw int32 }
|
||||
|
||||
func Q16(x int32) AvmVal { return AvmVal{ValQ16, x} }
|
||||
func Bool(x bool) AvmVal {
|
||||
if x { return AvmVal{ValBool, 1} }
|
||||
return AvmVal{ValBool, 0}
|
||||
}
|
||||
|
||||
// ── Primitives ─────────────────────────────────────
|
||||
type Prim int
|
||||
const (
|
||||
AddQ16 Prim = iota; SubQ16; MulQ16; DivQ16; LtQ16; EqQ16; And; Or; Not
|
||||
)
|
||||
|
||||
func execPrim(p Prim, a, b AvmVal) (AvmVal, error) {
|
||||
switch p {
|
||||
case AddQ16: return Q16(a.Raw + b.Raw), nil
|
||||
case SubQ16: return Q16(a.Raw - b.Raw), nil
|
||||
case MulQ16: return Q16(q16Mul(a.Raw, b.Raw)), nil
|
||||
case DivQ16:
|
||||
r, e := q16Div(a.Raw, b.Raw)
|
||||
return Q16(r), e
|
||||
case LtQ16: return Bool(a.Raw < b.Raw), nil
|
||||
case EqQ16: return Bool(a.Raw == b.Raw), nil
|
||||
case And: return Bool(a.Raw != 0 && b.Raw != 0), nil
|
||||
case Or: return Bool(a.Raw != 0 || b.Raw != 0), nil
|
||||
case Not: return Bool(a.Raw == 0), nil
|
||||
}
|
||||
return AvmVal{}, errors.New("unknown prim")
|
||||
}
|
||||
|
||||
// ── Instruction ────────────────────────────────────
|
||||
type InstrOp int
|
||||
const (
|
||||
PushQ16 InstrOp = iota; PushBool; Pop; Dup; Swap; Load; Store; Jump; JumpIf; PrimOp; Halt
|
||||
)
|
||||
type Instr struct { Op InstrOp; Arg int32; Arg2 bool }
|
||||
|
||||
func Push(x int32) Instr { return Instr{PushQ16, x, false} }
|
||||
func PushB(x bool) Instr { return Instr{PushBool, boolTo32(x), true} }
|
||||
func Pop() Instr { return Instr{Pop, 0, false} }
|
||||
func Dup() Instr { return Instr{Dup, 0, false} }
|
||||
func Swap() Instr { return Instr{Swap, 0, false} }
|
||||
func Load(i int) Instr { return Instr{Load, int32(i), false} }
|
||||
func Store(i int) Instr { return Instr{Store, int32(i), false} }
|
||||
func Jump(t int) Instr { return Instr{Jump, int32(t), false} }
|
||||
func JumpIf(t int) Instr { return Instr{JumpIf, int32(t), false} }
|
||||
func PrimOp(p Prim) Instr{ return Instr{PrimOp, int32(p), false} }
|
||||
func Halt() Instr { return Instr{Halt, 0, false} }
|
||||
|
||||
func boolTo32(x bool) int32 { if x { return 1 }; return 0 }
|
||||
|
||||
// ── State ──────────────────────────────────────────
|
||||
type State struct {
|
||||
Pc int
|
||||
Stack []AvmVal
|
||||
Locals []*AvmVal
|
||||
Halted bool
|
||||
}
|
||||
func NewState(n int) State {
|
||||
return State{0, []AvmVal{}, make([]*AvmVal, n), false}
|
||||
}
|
||||
|
||||
// ── Step ───────────────────────────────────────────
|
||||
func Step(s State, prog []Instr) (State, error) {
|
||||
if s.Halted { return s, errors.New("halted") }
|
||||
if s.Pc < 0 || s.Pc >= len(prog) {
|
||||
s.Halted = true; return s, nil
|
||||
}
|
||||
|
||||
instr := prog[s.Pc]
|
||||
ns := State{s.Pc + 1, append([]AvmVal{}, s.Stack...),
|
||||
append([]*AvmVal{}, s.Locals...), false}
|
||||
st := &ns.Stack
|
||||
|
||||
switch instr.Op {
|
||||
case PushQ16: *st = append(*st, Q16(instr.Arg))
|
||||
case PushBool: *st = append(*st, Bool(instr.Arg != 0))
|
||||
case Pop: *st = (*st)[:len(*st)-1]
|
||||
case Dup: *st = append(*st, (*st)[len(*st)-1])
|
||||
case Swap:
|
||||
(*st)[len(*st)-2], (*st)[len(*st)-1] = (*st)[len(*st)-1], (*st)[len(*st)-2]
|
||||
case Load:
|
||||
if ns.Locals[instr.Arg] == nil { return s, errors.New("missing local") }
|
||||
*st = append(*st, *ns.Locals[instr.Arg])
|
||||
case Store:
|
||||
ns.Locals[instr.Arg] = &(*st)[len(*st)-1]
|
||||
*st = (*st)[:len(*st)-1]
|
||||
case Jump: ns.Pc = int(instr.Arg)
|
||||
case JumpIf:
|
||||
v := (*st)[len(*st)-1]; *st = (*st)[:len(*st)-1]
|
||||
if v.Raw != 0 { ns.Pc = int(instr.Arg) }
|
||||
case PrimOp: {
|
||||
p := Prim(instr.Arg)
|
||||
arity := 2; if p == Not { arity = 1 }
|
||||
var b AvmVal
|
||||
if arity == 2 { b = (*st)[len(*st)-1]; *st = (*st)[:len(*st)-1] }
|
||||
a := (*st)[len(*st)-1]; *st = (*st)[:len(*st)-1]
|
||||
r, e := execPrim(p, a, b)
|
||||
if e != nil { return s, e }
|
||||
*st = append(*st, r)
|
||||
}
|
||||
case Halt: ns.Halted = true
|
||||
}
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func Run(init State, prog []Instr, fuel int) (State, error) {
|
||||
s := init
|
||||
for i := 0; i < fuel && !s.Halted; i++ {
|
||||
var e error
|
||||
s, e = Step(s, prog)
|
||||
if e != nil { return s, e }
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
112
go/avm_test.go
Normal file
112
go/avm_test.go
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
package avm
|
||||
|
||||
import "testing"
|
||||
|
||||
func q16(x int32) Val { return Val{Ty: Q16_16, Q: avmClamp(int64(x))} }
|
||||
|
||||
func runTest(prog []Instr, fuel int) (*State, error) {
|
||||
return Run(NewState(0), prog, fuel)
|
||||
}
|
||||
|
||||
func TestBasicAdd(t *testing.T) {
|
||||
prog := []Instr{
|
||||
{Op: PushQ16, Arg: 5 * Q16Scale},
|
||||
{Op: PushQ16, Arg: 3 * Q16Scale},
|
||||
{Op: Primitive, Arg: int32(AddSatQ16)},
|
||||
{Op: Halt},
|
||||
}
|
||||
s, err := runTest(prog, 100)
|
||||
if err != nil { t.Fatal(err) }
|
||||
if s.Stack[0].Q != 8*Q16Scale { t.Fatalf("got %d", s.Stack[0].Q) }
|
||||
}
|
||||
|
||||
func TestFloorDiv(t *testing.T) {
|
||||
// (3 * Q16) / (5 * Q16) = floor(0.6) = 0.6 in Q16
|
||||
prog := []Instr{
|
||||
{Op: PushQ16, Arg: 3 * Q16Scale},
|
||||
{Op: PushQ16, Arg: 5 * Q16Scale},
|
||||
{Op: Primitive, Arg: int32(DivSatQ16)},
|
||||
{Op: Halt},
|
||||
}
|
||||
s, err := runTest(prog, 100)
|
||||
if err != nil { t.Fatal(err) }
|
||||
expected := (3 * Q16Scale) / 5
|
||||
if s.Stack[0].Q != expected { t.Fatalf("got %d, expected %d", s.Stack[0].Q, expected) }
|
||||
}
|
||||
|
||||
func TestSaturation(t *testing.T) {
|
||||
prog := []Instr{
|
||||
{Op: PushQ16, Arg: AVMClampMax - 1},
|
||||
{Op: PushQ16, Arg: 2},
|
||||
{Op: Primitive, Arg: int32(AddSatQ16)},
|
||||
{Op: Halt},
|
||||
}
|
||||
s, err := runTest(prog, 100)
|
||||
if err != nil { t.Fatal(err) }
|
||||
if s.Stack[0].Q != AVMClampMax { t.Fatalf("got %d", s.Stack[0].Q) }
|
||||
}
|
||||
|
||||
func TestV6LtQ16(t *testing.T) {
|
||||
cases := []struct{ a, b int32; exp bool }{
|
||||
{-5 * Q16Scale, -3 * Q16Scale, true},
|
||||
{-3 * Q16Scale, -5 * Q16Scale, false},
|
||||
{5 * Q16Scale, 3 * Q16Scale, false},
|
||||
{3 * Q16Scale, 5 * Q16Scale, true},
|
||||
{-1 * Q16Scale, 2 * Q16Scale, true},
|
||||
}
|
||||
for _, c := range cases {
|
||||
prog := []Instr{
|
||||
{Op: PushQ16, Arg: c.a},
|
||||
{Op: PushQ16, Arg: c.b},
|
||||
{Op: Primitive, Arg: int32(LtQ16)},
|
||||
{Op: Halt},
|
||||
}
|
||||
s, err := runTest(prog, 100)
|
||||
if err != nil { t.Fatal(err) }
|
||||
if s.Stack[0].Bval != c.exp { t.Fatalf("ltQ16(%d,%d): got %v", c.a, c.b, s.Stack[0]) }
|
||||
}
|
||||
}
|
||||
|
||||
func TestDivByZero(t *testing.T) {
|
||||
prog := []Instr{
|
||||
{Op: PushQ16, Arg: Q16Scale},
|
||||
{Op: PushQ16, Arg: 0},
|
||||
{Op: Primitive, Arg: int32(DivSatQ16)},
|
||||
}
|
||||
_, err := runTest(prog, 100)
|
||||
if err == nil { t.Fatal("expected error") }
|
||||
}
|
||||
|
||||
func TestStackOverflow(t *testing.T) {
|
||||
prog := make([]Instr, AVMMaxStack+1)
|
||||
for i := range prog { prog[i] = Instr{Op: PushQ16, Arg: 0} }
|
||||
_, err := runTest(prog, 10000)
|
||||
if err == nil { t.Fatal("expected overflow") }
|
||||
}
|
||||
|
||||
func TestControlFlow(t *testing.T) {
|
||||
prog := []Instr{
|
||||
{Op: PushBool, Arg2: true},
|
||||
{Op: JumpIf, Arg: 4},
|
||||
{Op: PushQ16, Arg: 0},
|
||||
{Op: Halt},
|
||||
{Op: PushQ16, Arg: Q16Scale},
|
||||
{Op: Halt},
|
||||
}
|
||||
s, err := runTest(prog, 100)
|
||||
if err != nil { t.Fatal(err) }
|
||||
if s.Stack[0].Q != Q16Scale { t.Fatalf("got %d", s.Stack[0].Q) }
|
||||
}
|
||||
|
||||
func TestLocals(t *testing.T) {
|
||||
s := NewState(1)
|
||||
prog := []Instr{
|
||||
{Op: PushQ16, Arg: 42 * Q16Scale},
|
||||
{Op: Store, Arg: 0},
|
||||
{Op: Load, Arg: 0},
|
||||
{Op: Halt},
|
||||
}
|
||||
result, err := Run(s, prog, 100)
|
||||
if err != nil { t.Fatal(err) }
|
||||
if result.Stack[0].Q != 42*Q16Scale { t.Fatalf("got %d", result.Stack[0].Q) }
|
||||
}
|
||||
131
octave/AVMIsa/avm.m
Normal file
131
octave/AVMIsa/avm.m
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
% AVM ISA v1 — Octave Port (Strict Functional Execution)
|
||||
% All functions are pure (no global mutation).
|
||||
|
||||
Q16_SCALE = 65536;
|
||||
|
||||
function r = q16_mul(a, b)
|
||||
r = int32((int64(a) * int64(b)) / Q16_SCALE);
|
||||
end
|
||||
|
||||
function r = q16_div(a, b)
|
||||
if b == 0, error("div by zero"); end
|
||||
r = int32((int64(a) * Q16_SCALE) / int64(b));
|
||||
end
|
||||
|
||||
% ── Constructors ──────────────────────────────────
|
||||
function v = make_q16(x)
|
||||
v.ty = 'q16'; v.val = int32(x);
|
||||
end
|
||||
function v = make_bool(x)
|
||||
v.ty = 'bool'; v.val = int32(x);
|
||||
end
|
||||
function i = make_instr(op, arg)
|
||||
i.op = int8(op); i.arg = int32(arg);
|
||||
end
|
||||
|
||||
% ── Instructions ──────────────────────────────────
|
||||
function i = push_q16(x); i = make_instr(0, x); end
|
||||
function i = push_bool(x); i = make_instr(1, x); end
|
||||
function i = pop(); i = make_instr(2, 0); end
|
||||
function i = dup(); i = make_instr(3, 0); end
|
||||
function i = swap(); i = make_instr(4, 0); end
|
||||
function i = load(x); i = make_instr(5, x); end
|
||||
function i = store(x); i = make_instr(6, x); end
|
||||
function i = jump(x); i = make_instr(7, x); end
|
||||
function i = jump_if(x); i = make_instr(8, x); end
|
||||
function i = prim(x); i = make_instr(9, x); end
|
||||
function i = halt(); i = make_instr(10, 0); end
|
||||
|
||||
% Primitives
|
||||
PRIM_ADD=0; PRIM_SUB=1; PRIM_MUL=2; PRIM_DIV=3;
|
||||
PRIM_LT=4; PRIM_EQ=5; PRIM_AND=6; PRIM_OR=7; PRIM_NOT=8;
|
||||
|
||||
% ── State ─────────────────────────────────────────
|
||||
function s = new_state(n)
|
||||
s.pc = 1;
|
||||
s.stack = cell(1024, 1); s.sp = 0;
|
||||
s.locals = cell(n, 1);
|
||||
s.halted = false;
|
||||
end
|
||||
|
||||
function s = state_push(s, v)
|
||||
s.sp = s.sp + 1;
|
||||
s.stack{s.sp} = v;
|
||||
end
|
||||
|
||||
function [v, s] = state_pop(s)
|
||||
v = s.stack{s.sp};
|
||||
s.sp = s.sp - 1;
|
||||
end
|
||||
|
||||
% ── Step ──────────────────────────────────────────
|
||||
function ns = step(state, prog)
|
||||
ns = state;
|
||||
if ns.halted, return; end
|
||||
if ns.pc < 1 || ns.pc > length(prog)
|
||||
ns.halted = true; return;
|
||||
end
|
||||
|
||||
instr = prog{ns.pc};
|
||||
|
||||
switch instr.op
|
||||
case 0 % push_q16
|
||||
ns = state_push(ns, make_q16(instr.arg));
|
||||
case 1 % push_bool
|
||||
ns = state_push(ns, make_bool(instr.arg));
|
||||
case 2 % pop
|
||||
[~, ns] = state_pop(ns);
|
||||
case 3 % dup
|
||||
ns = state_push(ns, ns.stack{ns.sp});
|
||||
case 4 % swap
|
||||
[a, ns] = state_pop(ns); [b, ns] = state_pop(ns);
|
||||
ns = state_push(ns, a); ns = state_push(ns, b);
|
||||
case 5 % load
|
||||
ns = state_push(ns, ns.locals{instr.arg + 1});
|
||||
case 6 % store
|
||||
[v, ns] = state_pop(ns);
|
||||
ns.locals{instr.arg + 1} = v;
|
||||
case 7 % jump
|
||||
ns.pc = instr.arg; return;
|
||||
case 8 % jump_if
|
||||
[v, ns] = state_pop(ns);
|
||||
if v.val != 0, ns.pc = instr.arg; end
|
||||
case 9 % prim
|
||||
arity = 2;
|
||||
if instr.arg == PRIM_NOT, arity = 1; end
|
||||
if arity >= 2, [b, ns] = state_pop(ns); end
|
||||
[a, ns] = state_pop(ns);
|
||||
switch instr.arg
|
||||
case PRIM_ADD
|
||||
r = make_q16(a.val + b.val);
|
||||
case PRIM_SUB
|
||||
r = make_q16(a.val - b.val);
|
||||
case PRIM_MUL
|
||||
r = make_q16(q16_mul(a.val, b.val));
|
||||
case PRIM_DIV
|
||||
r = make_q16(q16_div(a.val, b.val));
|
||||
case PRIM_LT
|
||||
r = make_bool(a.val < b.val);
|
||||
case PRIM_EQ
|
||||
r = make_bool(a.val == b.val);
|
||||
case PRIM_AND
|
||||
r = make_bool(a.val && b.val);
|
||||
case PRIM_OR
|
||||
r = make_bool(a.val || b.val);
|
||||
case PRIM_NOT
|
||||
r = make_bool(a.val == 0);
|
||||
end
|
||||
ns = state_push(ns, r);
|
||||
case 10 % halt
|
||||
ns.halted = true;
|
||||
end
|
||||
ns.pc = ns.pc + 1;
|
||||
end
|
||||
|
||||
function s = run(init, prog, fuel)
|
||||
s = init;
|
||||
for i = 1:fuel
|
||||
if s.halted, break; end
|
||||
s = step(s, prog);
|
||||
end
|
||||
end
|
||||
308
python/avm.py
308
python/avm.py
|
|
@ -1,209 +1,199 @@
|
|||
"""
|
||||
AVM ISA v1 — Python Port (Strict Functional Execution)
|
||||
Mirrors formal/SilverSight/AVMIsa/Step.lean
|
||||
AVM ISA v1 — Python Port
|
||||
Strict functional: step(state, program) -> state, run(state, program, fuel) -> state
|
||||
"""
|
||||
from __future__ import annotations
|
||||
from dataclasses import dataclass, field
|
||||
from enum import IntEnum, auto
|
||||
from typing import Union, Optional
|
||||
import sys
|
||||
|
||||
from q16_canonical import Q16_SCALE, float_to_q16, q16_to_float
|
||||
from typing import List, Union, Tuple
|
||||
|
||||
# ── Constants ────────────────────────────────────────────────────────
|
||||
Q16_SCALE = 65536
|
||||
AVM_CLAMP_MIN = -2147483647
|
||||
AVM_CLAMP_MAX = 2147483647
|
||||
AVM_Q0_MIN = -32767
|
||||
AVM_Q0_MAX = 32767
|
||||
AVM_MAX_STACK = 1024
|
||||
|
||||
def avm_clamp(x: int) -> int:
|
||||
return max(AVM_CLAMP_MIN, min(AVM_CLAMP_MAX, x))
|
||||
def avm_clamp(x):
|
||||
return max(AVM_CLAMP_MIN, min(AVM_CLAMP_MAX, int(x)))
|
||||
|
||||
def avm_q0_clamp(x: int) -> int:
|
||||
return max(AVM_Q0_MIN, min(AVM_Q0_MAX, x))
|
||||
def avm_q0_clamp(x):
|
||||
return max(AVM_Q0_MIN, min(AVM_Q0_MAX, int(x)))
|
||||
|
||||
def floor_div(a: int, b: int) -> int:
|
||||
"""Floor division matching Lean Int.ediv."""
|
||||
if b == 0:
|
||||
raise ValueError("division by zero")
|
||||
return -((-a) // b) if (a < 0) != (b < 0) and a % b != 0 else a // b
|
||||
def floor_div(a, b):
|
||||
if b == 0: raise ValueError("div by zero")
|
||||
q, r = divmod(a, b)
|
||||
return q - 1 if r and (a ^ b) < 0 else q
|
||||
|
||||
def lt_q16_v6(a: int, b: int) -> bool:
|
||||
sa = a < 0
|
||||
sb = b < 0
|
||||
def lt_q16_v6(a, b):
|
||||
sa, sb = a < 0, b < 0
|
||||
return sa if sa != sb else a < b
|
||||
|
||||
def q16_mul(a, b):
|
||||
return floor_div(a * b, Q16_SCALE)
|
||||
|
||||
def q16_div(a, b):
|
||||
if b == 0: raise ValueError("div by zero")
|
||||
return floor_div(a * Q16_SCALE, b)
|
||||
|
||||
# ── Types ────────────────────────────────────────────────────────────
|
||||
class AvmTy(IntEnum):
|
||||
Q0_16 = 0
|
||||
Q16_16 = 1
|
||||
BOOL = 2
|
||||
class Prim:
|
||||
ADD_SAT_Q0, SUB_SAT_Q0, ADD_SAT_Q16, SUB_SAT_Q16, \
|
||||
MUL_SAT_Q16, DIV_SAT_Q16, LT_Q16, EQ_Q16, AND, OR, NOT = range(11)
|
||||
|
||||
# ── Values ───────────────────────────────────────────────────────────
|
||||
@dataclass
|
||||
class AnyVal:
|
||||
ty: AvmTy
|
||||
val: Union[int, bool]
|
||||
prim_arity = {Prim.NOT: 1}.get # all others are 2
|
||||
|
||||
class AvmVal:
|
||||
def __init__(self, ty, val):
|
||||
self.ty = ty
|
||||
self.val = val
|
||||
@staticmethod
|
||||
def q16(x: int) -> 'AnyVal':
|
||||
return AnyVal(AvmTy.Q16_16, avm_clamp(x))
|
||||
def q0(x): return AvmVal('q0', avm_q0_clamp(x))
|
||||
@staticmethod
|
||||
def q0(x: int) -> 'AnyVal':
|
||||
return AnyVal(AvmTy.Q0_16, avm_q0_clamp(x))
|
||||
def q16(x): return AvmVal('q16', avm_clamp(x))
|
||||
@staticmethod
|
||||
def b(x: bool) -> 'AnyVal':
|
||||
return AnyVal(AvmTy.BOOL, x)
|
||||
|
||||
# ── Instructions ─────────────────────────────────────────────────────
|
||||
class Prim(IntEnum):
|
||||
ADD_SAT_Q0 = 0
|
||||
SUB_SAT_Q0 = 1
|
||||
ADD_SAT_Q16 = 2
|
||||
SUB_SAT_Q16 = 3
|
||||
MUL_SAT_Q16 = 4
|
||||
DIV_SAT_Q16 = 5
|
||||
LT_Q16 = 6
|
||||
EQ_Q16 = 7
|
||||
AND = 8
|
||||
OR = 9
|
||||
NOT = 10
|
||||
|
||||
@property
|
||||
def arity(self) -> int:
|
||||
return 1 if self == Prim.NOT else 2
|
||||
def bool(x): return AvmVal('bool', bool(x))
|
||||
|
||||
class Instr:
|
||||
PUSH_Q16, PUSH_BOOL, PUSH_Q0, POP, DUP, SWAP, LOAD, STORE, JUMP, JUMP_IF, PRIM, HALT = range(12)
|
||||
PUSH, PUSH_BOOL, PUSH_Q0, POP, DUP, SWAP, LOAD, STORE, \
|
||||
JUMP, JUMP_IF, PRIM, HALT = range(12)
|
||||
|
||||
# ── Primitive execution ──────────────────────────────────────────────
|
||||
def eval_prim(p: Prim, a: AnyVal, b: Optional[AnyVal] = None) -> AnyVal:
|
||||
if p == Prim.ADD_SAT_Q0:
|
||||
assert a.ty == b.ty == AvmTy.Q0_16
|
||||
return AnyVal.q0(a.val + b.val)
|
||||
elif p == Prim.SUB_SAT_Q0:
|
||||
assert a.ty == b.ty == AvmTy.Q0_16
|
||||
return AnyVal.q0(a.val - b.val)
|
||||
elif p == Prim.ADD_SAT_Q16:
|
||||
assert a.ty == b.ty == AvmTy.Q16_16
|
||||
return AnyVal.q16(a.val + b.val)
|
||||
elif p == Prim.SUB_SAT_Q16:
|
||||
assert a.ty == b.ty == AvmTy.Q16_16
|
||||
return AnyVal.q16(a.val - b.val)
|
||||
elif p == Prim.MUL_SAT_Q16:
|
||||
assert a.ty == b.ty == AvmTy.Q16_16
|
||||
return AnyVal.q16(floor_div(a.val * b.val, Q16_SCALE))
|
||||
elif p == Prim.DIV_SAT_Q16:
|
||||
assert a.ty == b.ty == AvmTy.Q16_16
|
||||
if b.val == 0:
|
||||
raise ValueError("division by zero")
|
||||
return AnyVal.q16(floor_div(a.val * Q16_SCALE, b.val))
|
||||
elif p == Prim.LT_Q16:
|
||||
assert a.ty == b.ty == AvmTy.Q16_16
|
||||
return AnyVal.b(lt_q16_v6(a.val, b.val))
|
||||
elif p == Prim.EQ_Q16:
|
||||
assert a.ty == b.ty == AvmTy.Q16_16
|
||||
return AnyVal.b(a.val == b.val)
|
||||
elif p == Prim.AND:
|
||||
assert a.ty == b.ty == AvmTy.BOOL
|
||||
return AnyVal.b(a.val and b.val)
|
||||
elif p == Prim.OR:
|
||||
assert a.ty == b.ty == AvmTy.BOOL
|
||||
return AnyVal.b(a.val or b.val)
|
||||
elif p == Prim.NOT:
|
||||
assert a.ty == AvmTy.BOOL
|
||||
return AnyVal.b(not a.val)
|
||||
Q0_OPS = {Prim.ADD_SAT_Q0, Prim.SUB_SAT_Q0}
|
||||
Q16_BIN_OPS = {Prim.ADD_SAT_Q16, Prim.SUB_SAT_Q16, Prim.MUL_SAT_Q16, Prim.DIV_SAT_Q16, Prim.LT_Q16, Prim.EQ_Q16}
|
||||
BOOL_BIN_OPS = {Prim.AND, Prim.OR}
|
||||
|
||||
# ── Errors ───────────────────────────────────────────────────────────
|
||||
class StepError(Exception):
|
||||
def __init__(self, kind: str):
|
||||
self.kind = kind
|
||||
def check_type(val_ty, expected, label):
|
||||
if val_ty != expected:
|
||||
raise TypeError(f"type mismatch: expected {expected}, got {val_ty}")
|
||||
|
||||
def make_instr(op, arg=None, arg2=None):
|
||||
return {'op': op, 'arg': arg, 'arg2': arg2}
|
||||
|
||||
def push_q16(x): return make_instr(Instr.PUSH, avm_clamp(x))
|
||||
def push_bool(x): return make_instr(Instr.PUSH_BOOL, 0, x)
|
||||
def push_q0(x): return make_instr(Instr.PUSH_Q0, avm_q0_clamp(x))
|
||||
def pop(): return make_instr(Instr.POP)
|
||||
def dup(): return make_instr(Instr.DUP)
|
||||
def swap(): return make_instr(Instr.SWAP)
|
||||
def load(i): return make_instr(Instr.LOAD, i)
|
||||
def store(i): return make_instr(Instr.STORE, i)
|
||||
def jump(t): return make_instr(Instr.JUMP, t)
|
||||
def jump_if(t): return make_instr(Instr.JUMP_IF, t)
|
||||
def prim(p): return make_instr(Instr.PRIM, p)
|
||||
def halt(): return make_instr(Instr.HALT)
|
||||
|
||||
# ── State ────────────────────────────────────────────────────────────
|
||||
@dataclass
|
||||
class State:
|
||||
pc: int = 0
|
||||
stack: list = field(default_factory=list)
|
||||
locals: list = field(default_factory=list)
|
||||
locals: list = field(default_factory=lambda: [None] * 16)
|
||||
halted: bool = False
|
||||
|
||||
@staticmethod
|
||||
def new(n_locals: int = 0):
|
||||
return State(pc=0, stack=[], locals=[None] * n_locals, halted=False)
|
||||
# ── Primitive execution ──────────────────────────────────────────────
|
||||
def exec_prim(op, a, b=None):
|
||||
if op == Prim.ADD_SAT_Q0:
|
||||
check_type(a.ty, 'q0', 'a'); check_type(b.ty, 'q0', 'b')
|
||||
return AvmVal.q0(a.val + b.val)
|
||||
if op == Prim.SUB_SAT_Q0:
|
||||
check_type(a.ty, 'q0', 'a'); check_type(b.ty, 'q0', 'b')
|
||||
return AvmVal.q0(a.val - b.val)
|
||||
if op == Prim.ADD_SAT_Q16:
|
||||
check_type(a.ty, 'q16', 'a'); check_type(b.ty, 'q16', 'b')
|
||||
return AvmVal.q16(a.val + b.val)
|
||||
if op == Prim.SUB_SAT_Q16:
|
||||
check_type(a.ty, 'q16', 'a'); check_type(b.ty, 'q16', 'b')
|
||||
return AvmVal.q16(a.val - b.val)
|
||||
if op == Prim.MUL_SAT_Q16:
|
||||
check_type(a.ty, 'q16', 'a'); check_type(b.ty, 'q16', 'b')
|
||||
return AvmVal.q16(q16_mul(a.val, b.val))
|
||||
if op == Prim.DIV_SAT_Q16:
|
||||
check_type(a.ty, 'q16', 'a'); check_type(b.ty, 'q16', 'b')
|
||||
if b.val == 0: raise ValueError("division by zero")
|
||||
return AvmVal.q16(q16_div(a.val, b.val))
|
||||
if op == Prim.LT_Q16:
|
||||
check_type(a.ty, 'q16', 'a'); check_type(b.ty, 'q16', 'b')
|
||||
return AvmVal.bool(lt_q16_v6(a.val, b.val))
|
||||
if op == Prim.EQ_Q16:
|
||||
check_type(a.ty, 'q16', 'a'); check_type(b.ty, 'q16', 'b')
|
||||
return AvmVal.bool(a.val == b.val)
|
||||
if op == Prim.AND:
|
||||
check_type(a.ty, 'bool', 'a'); check_type(b.ty, 'bool', 'b')
|
||||
return AvmVal.bool(a.val and b.val)
|
||||
if op == Prim.OR:
|
||||
check_type(a.ty, 'bool', 'a'); check_type(b.ty, 'bool', 'b')
|
||||
return AvmVal.bool(a.val or b.val)
|
||||
if op == Prim.NOT:
|
||||
check_type(a.ty, 'bool', 'a')
|
||||
return AvmVal.bool(not a.val)
|
||||
raise TypeError(f"unknown prim {op}")
|
||||
|
||||
# ── Step ─────────────────────────────────────────────────────────────
|
||||
def step(s: State, prog: list) -> State:
|
||||
if s.halted:
|
||||
raise StepError("halted")
|
||||
if s.pc < 0 or s.pc >= len(prog):
|
||||
return State(pc=s.pc, stack=list(s.stack), locals=list(s.locals), halted=True)
|
||||
def step(state, program):
|
||||
if state.halted: raise ValueError("halted")
|
||||
if state.pc < 0 or state.pc >= len(program):
|
||||
return State(state.pc, list(state.stack), list(state.locals), True)
|
||||
|
||||
instr = prog[s.pc]
|
||||
stack = list(s.stack)
|
||||
pc = s.pc + 1
|
||||
instr = program[state.pc]
|
||||
stack = list(state.stack)
|
||||
locals = list(state.locals)
|
||||
pc = state.pc + 1
|
||||
halted = False
|
||||
|
||||
GROW_OPS = {Instr.PUSH_Q16, Instr.PUSH_BOOL, Instr.PUSH_Q0, Instr.DUP, Instr.LOAD}
|
||||
if instr[0] in GROW_OPS and len(stack) >= AVM_MAX_STACK:
|
||||
raise StepError("stack_overflow")
|
||||
growing = instr['op'] in (Instr.PUSH, Instr.PUSH_BOOL, Instr.PUSH_Q0, Instr.DUP, Instr.LOAD)
|
||||
if growing and len(stack) >= AVM_MAX_STACK:
|
||||
raise ValueError("stack overflow")
|
||||
|
||||
op = instr[0]
|
||||
arg = instr[1]
|
||||
arg2 = instr[2] if len(instr) > 2 else None
|
||||
|
||||
if op == Instr.PUSH_Q16:
|
||||
stack.append(AnyVal.q16(arg))
|
||||
elif op == Instr.PUSH_BOOL:
|
||||
stack.append(AnyVal.b(arg2))
|
||||
elif op == Instr.PUSH_Q0:
|
||||
stack.append(AnyVal.q0(arg))
|
||||
elif op == Instr.POP:
|
||||
if not stack: raise StepError("empty_stack")
|
||||
if instr['op'] == Instr.PUSH:
|
||||
stack.append(AvmVal.q16(instr['arg']))
|
||||
elif instr['op'] == Instr.PUSH_BOOL:
|
||||
stack.append(AvmVal.bool(instr['arg2']))
|
||||
elif instr['op'] == Instr.PUSH_Q0:
|
||||
stack.append(AvmVal.q0(instr['arg']))
|
||||
elif instr['op'] == Instr.POP:
|
||||
if not stack: raise ValueError("empty stack")
|
||||
stack.pop()
|
||||
elif op == Instr.DUP:
|
||||
if not stack: raise StepError("empty_stack")
|
||||
elif instr['op'] == Instr.DUP:
|
||||
if not stack: raise ValueError("empty stack")
|
||||
stack.append(stack[-1])
|
||||
elif op == Instr.SWAP:
|
||||
if len(stack) < 2: raise StepError("stack_underflow")
|
||||
elif instr['op'] == Instr.SWAP:
|
||||
if len(stack) < 2: raise ValueError("stack underflow")
|
||||
stack[-1], stack[-2] = stack[-2], stack[-1]
|
||||
elif op == Instr.LOAD:
|
||||
if arg >= len(s.locals) or s.locals[arg] is None:
|
||||
raise StepError("missing_local")
|
||||
stack.append(s.locals[arg])
|
||||
elif op == Instr.STORE:
|
||||
if not stack: raise StepError("empty_stack")
|
||||
if arg >= len(s.locals): raise StepError("missing_local")
|
||||
s.locals[arg] = stack.pop()
|
||||
elif op == Instr.JUMP:
|
||||
if arg < 0 or arg >= len(prog): raise StepError("jump_out_of_bounds")
|
||||
pc = arg
|
||||
elif op == Instr.JUMP_IF:
|
||||
if not stack: raise StepError("empty_stack")
|
||||
cond = stack.pop()
|
||||
if cond.ty != AvmTy.BOOL: raise StepError("type_mismatch")
|
||||
if cond.val:
|
||||
if arg < 0 or arg >= len(prog): raise StepError("jump_out_of_bounds")
|
||||
pc = arg
|
||||
elif op == Instr.PRIM:
|
||||
p = Prim(arg)
|
||||
arity = p.arity
|
||||
if len(stack) < arity: raise StepError("stack_underflow")
|
||||
elif instr['op'] == Instr.LOAD:
|
||||
i = instr['arg']
|
||||
if i >= len(locals) or locals[i] is None: raise ValueError("missing local")
|
||||
stack.append(locals[i])
|
||||
elif instr['op'] == Instr.STORE:
|
||||
if not stack: raise ValueError("empty stack")
|
||||
i = instr['arg']
|
||||
if i >= len(locals): raise ValueError("missing local")
|
||||
locals[i] = stack.pop()
|
||||
elif instr['op'] == Instr.JUMP:
|
||||
if instr['arg'] < 0 or instr['arg'] >= len(program): raise ValueError("jump OOB")
|
||||
pc = instr['arg']
|
||||
elif instr['op'] == Instr.JUMP_IF:
|
||||
if not stack: raise ValueError("empty stack")
|
||||
v = stack.pop()
|
||||
if v.ty != 'bool': raise TypeError("type mismatch")
|
||||
if v.val:
|
||||
if instr['arg'] < 0 or instr['arg'] >= len(program): raise ValueError("jump OOB")
|
||||
pc = instr['arg']
|
||||
elif instr['op'] == Instr.PRIM:
|
||||
p = instr['arg']
|
||||
arity = 1 if p == Prim.NOT else 2
|
||||
if len(stack) < arity: raise ValueError("stack underflow")
|
||||
b = stack.pop() if arity >= 2 else None
|
||||
a = stack.pop()
|
||||
stack.append(eval_prim(p, a, b))
|
||||
elif op == Instr.HALT:
|
||||
stack.append(exec_prim(p, a, b))
|
||||
elif instr['op'] == Instr.HALT:
|
||||
halted = True
|
||||
else:
|
||||
raise StepError("unknown_instr")
|
||||
raise ValueError(f"unknown instr {instr['op']}")
|
||||
|
||||
return State(pc=pc, stack=stack, locals=list(s.locals), halted=halted)
|
||||
return State(pc, stack, locals, halted)
|
||||
|
||||
# ── Run (fuel-bounded) ──────────────────────────────────────────────
|
||||
def run(initial: State, prog: list, fuel: int = 10000) -> State:
|
||||
s = initial
|
||||
def run(initial, program, fuel=1000):
|
||||
state = initial
|
||||
for _ in range(fuel):
|
||||
if s.halted:
|
||||
return s
|
||||
s = step(s, prog)
|
||||
return s
|
||||
if state.halted: return state
|
||||
state = step(state, program)
|
||||
return state
|
||||
|
|
|
|||
101
scala/AVMIsa/avm.scala
Normal file
101
scala/AVMIsa/avm.scala
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// AVM ISA v1 — Scala Port (Strict Functional Execution)
|
||||
package avm
|
||||
|
||||
object AVM {
|
||||
val Q16Scale: Int = 65536
|
||||
|
||||
def q16Mul(a: Int, b: Int): Int = ((a.toLong * b.toLong) / Q16Scale).toInt
|
||||
def q16Div(a: Int, b: Int): Int = {
|
||||
if (b == 0) throw new ArithmeticException("div by zero")
|
||||
((a.toLong * Q16Scale) / b).toInt
|
||||
}
|
||||
|
||||
// ── Types ───────────────────────────────────────
|
||||
sealed trait ValType
|
||||
case object Q0 extends ValType
|
||||
case object Q16 extends ValType
|
||||
case object BoolT extends ValType
|
||||
|
||||
case class AvmVal(ty: ValType, raw: Int)
|
||||
object AvmVal {
|
||||
def q16(x: Int): AvmVal = AvmVal(Q16, x)
|
||||
def bool(x: Boolean): AvmVal = AvmVal(BoolT, if (x) 1 else 0)
|
||||
}
|
||||
|
||||
// ── Primitives ──────────────────────────────────
|
||||
sealed trait Prim
|
||||
case object AddQ16 extends Prim; case object SubQ16 extends Prim
|
||||
case object MulQ16 extends Prim; case object DivQ16 extends Prim
|
||||
case object LtQ16 extends Prim; case object EqQ16 extends Prim
|
||||
case object And extends Prim; case object Or extends Prim; case object Not extends Prim
|
||||
|
||||
def execPrim(p: Prim, a: AvmVal, b: Option[AvmVal]): AvmVal = (p, b) match {
|
||||
case (AddQ16, Some(bv)) => AvmVal.q16(a.raw + bv.raw)
|
||||
case (SubQ16, Some(bv)) => AvmVal.q16(a.raw - bv.raw)
|
||||
case (MulQ16, Some(bv)) => AvmVal.q16(q16Mul(a.raw, bv.raw))
|
||||
case (DivQ16, Some(bv)) => AvmVal.q16(q16Div(a.raw, bv.raw))
|
||||
case (LtQ16, Some(bv)) => AvmVal.bool(a.raw < bv.raw)
|
||||
case (EqQ16, Some(bv)) => AvmVal.bool(a.raw == bv.raw)
|
||||
case (And, Some(bv)) => AvmVal.bool(a.raw != 0 && bv.raw != 0)
|
||||
case (Or, Some(bv)) => AvmVal.bool(a.raw != 0 || bv.raw != 0)
|
||||
case (Not, _) => AvmVal.bool(a.raw == 0)
|
||||
case _ => throw new RuntimeException("type mismatch")
|
||||
}
|
||||
|
||||
// ── Instructions ────────────────────────────────
|
||||
sealed trait Instr
|
||||
case class PushQ16(x: Int) extends Instr
|
||||
case class PushBool(x: Boolean) extends Instr
|
||||
case object Pop extends Instr; case object Dup extends Instr
|
||||
case object Swap extends Instr
|
||||
case class Load(i: Int) extends Instr; case class Store(i: Int) extends Instr
|
||||
case class Jump(t: Int) extends Instr; case class JumpIf(t: Int) extends Instr
|
||||
case class PrimOp(p: Prim) extends Instr; case object Halt extends Instr
|
||||
|
||||
// ── State ───────────────────────────────────────
|
||||
case class State(pc: Int, stack: List[AvmVal], locals: Vector[Option[AvmVal]],
|
||||
halted: Boolean)
|
||||
object State { def apply(nLocals: Int = 0): State =
|
||||
State(0, Nil, Vector.fill(nLocals)(None), false)
|
||||
}
|
||||
|
||||
// ── Step ────────────────────────────────────────
|
||||
def step(s: State, prog: Vector[Instr]): State = {
|
||||
if (s.halted) throw new RuntimeException("halted")
|
||||
if (s.pc < 0 || s.pc >= prog.length) return s.copy(halted = true)
|
||||
|
||||
prog(s.pc) match {
|
||||
case PushQ16(x) => s.copy(pc = s.pc + 1, stack = AvmVal.q16(x) :: s.stack)
|
||||
case PushBool(x) => s.copy(pc = s.pc + 1, stack = AvmVal.bool(x) :: s.stack)
|
||||
case Pop => s.copy(pc = s.pc + 1, stack = s.stack.tail)
|
||||
case Dup => s.copy(pc = s.pc + 1, stack = s.stack.head :: s.stack)
|
||||
case Swap =>
|
||||
val a :: b :: rest = s.stack
|
||||
s.copy(pc = s.pc + 1, stack = b :: a :: rest)
|
||||
case Load(i) =>
|
||||
val v = s.locals(i).getOrElse(throw new RuntimeException("missing local"))
|
||||
s.copy(pc = s.pc + 1, stack = v :: s.stack)
|
||||
case Store(i) =>
|
||||
s.copy(pc = s.pc + 1, locals = s.locals.updated(i, Some(s.stack.head)),
|
||||
stack = s.stack.tail)
|
||||
case Jump(t) => s.copy(pc = t)
|
||||
case JumpIf(t) =>
|
||||
if (s.stack.head.raw != 0) s.copy(pc = t, stack = s.stack.tail)
|
||||
else s.copy(pc = s.pc + 1, stack = s.stack.tail)
|
||||
case PrimOp(p) =>
|
||||
val arity = if (p == Not) 1 else 2
|
||||
val b = if (arity >= 2) Some(s.stack.head) else None
|
||||
val rest = if (arity >= 2) s.stack.tail else s.stack
|
||||
val a = rest.head
|
||||
val result = execPrim(p, a, b)
|
||||
s.copy(pc = s.pc + 1, stack = result :: rest.tail)
|
||||
case Halt => s.copy(halted = true)
|
||||
}
|
||||
}
|
||||
|
||||
def run(init: State, prog: Vector[Instr], fuel: Int): State = {
|
||||
var s = init
|
||||
for (_ <- 0 until fuel if !s.halted) s = step(s, prog)
|
||||
s
|
||||
}
|
||||
}
|
||||
95
scripts/wolfram_verify.py
Normal file
95
scripts/wolfram_verify.py
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Wolfram Alpha Mathematical Verification — SilverSight
|
||||
Verifies all core mathematical claims of the project.
|
||||
"""
|
||||
import urllib.request, urllib.parse, json, sys, os, hashlib
|
||||
|
||||
APPID = "HYJE3R3R63"
|
||||
|
||||
QUERIES = {
|
||||
# ── Q16_16 fixed-point arithmetic ─────────────────────────────
|
||||
"q16_scale_factor": "65536",
|
||||
"q16_mul_identity": "simplify (a * b / 65536) when a = 65536",
|
||||
"q16_saturation_bounds": "range of int32 signed integer",
|
||||
|
||||
# ── Rossby/Kelvin wave correspondence ─────────────────────────
|
||||
"rossby_dispersion": "omega = -beta * k / (k^2 + l^2) Rossby wave dispersion",
|
||||
"kelvin_wave_nondispersive": "omega = k * sqrt(g * H) Kelvin wave",
|
||||
"rossby_deformation_radius": "L_D = sqrt(g * H) / f Rossby deformation radius",
|
||||
|
||||
# ── Golden ratio / corkscrew ──────────────────────────────────
|
||||
"golden_ratio_conjugate": "solve x^2 - x - 1 = 0",
|
||||
"corkscrew_angle": "2 * pi / ((1 + sqrt(5)) / 2)^2",
|
||||
|
||||
# ── Fisher information metric ─────────────────────────────────
|
||||
"fisher_metric_simplex": "arccos(sum sqrt(p_i * q_i))",
|
||||
"fisher_distance": "2 * arccos(sqrt(p * q)) Fisher distance",
|
||||
"cauchy_schwarz_fisher": "sum sqrt(p_i * q_i) <= 1 for probability distributions",
|
||||
|
||||
# ── Eigensolid convergence ────────────────────────────────────
|
||||
"pair_averaging_idempotent": "simplify ((a+b)/2 + (c+d)/2) / 2",
|
||||
"pair_averaging_contractive": "prove |(a+b)/2 - (c+d)/2| < |a-c| + |b-d|",
|
||||
"chaos_game_contraction": "prove (1-eps)^k < 2^(-k) for 0 < eps < 1",
|
||||
|
||||
# ── NUVMAP projection ─────────────────────────────────────────
|
||||
"nuvmap_eigenmass": "limit lambda * v * S * L / (R + epsilon) as R -> 0",
|
||||
"bekenstein_bound": "A / (4 * L_p^2) Bekenstein bound",
|
||||
"eigenvalue_power_iteration": "Rayleigh quotient convergence power iteration",
|
||||
|
||||
# ── Sidon sets ────────────────────────────────────────────────
|
||||
"sidon_condition": "powers of 2 pairwise distinct sums",
|
||||
"sidon_slack_128": "128 - 2^7 =",
|
||||
"binary_sidon_max_sum": "max sum of distinct powers of 2 from 1,2,4,...,128",
|
||||
}
|
||||
|
||||
def query_wolfram(query):
|
||||
encoded = urllib.parse.quote_plus(query)
|
||||
url = f"http://api.wolframalpha.com/v2/query?appid={APPID}&input={encoded}&format=plaintext&output=JSON"
|
||||
try:
|
||||
req = urllib.request.Request(url, headers={'User-Agent': 'SilverSight/1.0'})
|
||||
with urllib.request.urlopen(req, timeout=15) as resp:
|
||||
return json.loads(resp.read().decode('utf-8'))
|
||||
except Exception as e:
|
||||
return {"error": str(e)}
|
||||
|
||||
def extract_result(res):
|
||||
if "error" in res:
|
||||
return f"[ERROR: {res['error']}]"
|
||||
if "queryresult" not in res:
|
||||
return "[no queryresult]"
|
||||
qr = res["queryresult"]
|
||||
for pod in qr.get("pods", []):
|
||||
for subpod in pod.get("subpods", []):
|
||||
if "plaintext" in subpod and subpod["plaintext"]:
|
||||
return subpod["plaintext"]
|
||||
return "[no plaintext result]"
|
||||
|
||||
def main():
|
||||
results = {}
|
||||
for name, query in QUERIES.items():
|
||||
print(f" {name}...", end=" ", flush=True)
|
||||
resp = query_wolfram(query)
|
||||
text = extract_result(resp)
|
||||
results[name] = {"query": query, "result": text}
|
||||
print(text[:80] if text else "(empty)")
|
||||
|
||||
# Build receipt
|
||||
receipt = {
|
||||
"schema": "wolfram_verification_v2",
|
||||
"generated_at": __import__('datetime').datetime.utcnow().isoformat(),
|
||||
"n_queries": len(QUERIES),
|
||||
"queries": results,
|
||||
"claim_boundary": "wolfram-alpha-algebraic-verification-only",
|
||||
}
|
||||
payload = json.dumps(results, sort_keys=True).encode()
|
||||
receipt["receipt_hash"] = hashlib.sha256(payload).hexdigest()[:16]
|
||||
|
||||
path = os.path.expanduser("~/SilverSight/signatures/wolfram_verification_receipt.json")
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
with open(path, "w") as f:
|
||||
json.dump(receipt, f, indent=2)
|
||||
print(f"\nReceipt: {path}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
89
signatures/wolfram_verification_receipt.json
Normal file
89
signatures/wolfram_verification_receipt.json
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
{
|
||||
"schema": "wolfram_verification_v2",
|
||||
"generated_at": "2026-06-30T22:50:11.469446",
|
||||
"n_queries": 20,
|
||||
"queries": {
|
||||
"q16_scale_factor": {
|
||||
"query": "65536",
|
||||
"result": "65536"
|
||||
},
|
||||
"q16_mul_identity": {
|
||||
"query": "simplify (a * b / 65536) when a = 65536",
|
||||
"result": "simplify | a \u00d7 b/65536 where a = 65536"
|
||||
},
|
||||
"q16_saturation_bounds": {
|
||||
"query": "range of int32 signed integer",
|
||||
"result": "[no plaintext result]"
|
||||
},
|
||||
"rossby_dispersion": {
|
||||
"query": "omega = -beta * k / (k^2 + l^2) Rossby wave dispersion",
|
||||
"result": "[no plaintext result]"
|
||||
},
|
||||
"kelvin_wave_nondispersive": {
|
||||
"query": "omega = k * sqrt(g * H) Kelvin wave",
|
||||
"result": "[no plaintext result]"
|
||||
},
|
||||
"rossby_deformation_radius": {
|
||||
"query": "L_D = sqrt(g * H) / f Rossby deformation radius",
|
||||
"result": "[no plaintext result]"
|
||||
},
|
||||
"golden_ratio_conjugate": {
|
||||
"query": "solve x^2 - x - 1 = 0",
|
||||
"result": "solve x^2 - x - 1 = 0"
|
||||
},
|
||||
"corkscrew_angle": {
|
||||
"query": "2 * pi / ((1 + sqrt(5)) / 2)^2",
|
||||
"result": "2 \u00d7 \u03c0/(1/2 (1 + sqrt(5)))^2"
|
||||
},
|
||||
"fisher_metric_simplex": {
|
||||
"query": "arccos(sum sqrt(p_i * q_i))",
|
||||
"result": "cos^(-1)( sum sqrt(p_i q_i))"
|
||||
},
|
||||
"fisher_distance": {
|
||||
"query": "2 * arccos(sqrt(p * q)) Fisher distance",
|
||||
"result": "2 cos^(-1)(sqrt(p q)) distance | from | near HradecKralove, Kralovehradecky\nto | Fisher, Mobile, United States"
|
||||
},
|
||||
"cauchy_schwarz_fisher": {
|
||||
"query": "sum sqrt(p_i * q_i) <= 1 for probability distributions",
|
||||
"result": "sum sqrt(p_i q_i) P(X<=1) where \nX distributed normal distribution | mean | \u03bc = 0\nstandard deviation | \u03c3 = 1"
|
||||
},
|
||||
"pair_averaging_idempotent": {
|
||||
"query": "simplify ((a+b)/2 + (c+d)/2) / 2",
|
||||
"result": "simplify | 1/2 ((a + b)/2 + (c + d)/2)"
|
||||
},
|
||||
"pair_averaging_contractive": {
|
||||
"query": "prove |(a+b)/2 - (c+d)/2| < |a-c| + |b-d|",
|
||||
"result": "simplify | abs((a + b)/2 - (c + d)/2)<abs(a - c) + abs(b - d)"
|
||||
},
|
||||
"chaos_game_contraction": {
|
||||
"query": "prove (1-eps)^k < 2^(-k) for 0 < eps < 1",
|
||||
"result": "simplify | (1 - \u03f5)^k<2^(-k) \u00d7 0<\u03f5<1"
|
||||
},
|
||||
"nuvmap_eigenmass": {
|
||||
"query": "limit lambda * v * S * L / (R + epsilon) as R -> 0",
|
||||
"result": "lim_(R->0) (\u03bb v S L)/(R + \u03f5) = (L S v \u03bb)/\u03f5"
|
||||
},
|
||||
"bekenstein_bound": {
|
||||
"query": "A / (4 * L_p^2) Bekenstein bound",
|
||||
"result": "[no plaintext result]"
|
||||
},
|
||||
"eigenvalue_power_iteration": {
|
||||
"query": "Rayleigh quotient convergence power iteration",
|
||||
"result": "[no plaintext result]"
|
||||
},
|
||||
"sidon_condition": {
|
||||
"query": "powers of 2 pairwise distinct sums",
|
||||
"result": "[no plaintext result]"
|
||||
},
|
||||
"sidon_slack_128": {
|
||||
"query": "128 - 2^7 =",
|
||||
"result": "128 - 2^7"
|
||||
},
|
||||
"binary_sidon_max_sum": {
|
||||
"query": "max sum of distinct powers of 2 from 1,2,4,...,128",
|
||||
"result": "[no plaintext result]"
|
||||
}
|
||||
},
|
||||
"claim_boundary": "wolfram-alpha-algebraic-verification-only",
|
||||
"receipt_hash": "a75dda235676ea71"
|
||||
}
|
||||
95
tests/test_avm_python.py
Normal file
95
tests/test_avm_python.py
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
"""
|
||||
AVM ISA v1 — Cross-Validated Test Harness (Python)
|
||||
"""
|
||||
import sys, os
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'python'))
|
||||
from avm import Instr, Prim, State, run, push_q16, push_bool, push_q0, prim, pop, dup, swap, store, load, \
|
||||
halt, jump, jump_if, make_instr, Q16_SCALE, AVM_CLAMP_MIN, AVM_CLAMP_MAX
|
||||
|
||||
AVM_CLAMP_MAX = 2147483647
|
||||
AVM_MAX_STACK = 1024
|
||||
|
||||
def S(nl=0): return State(pc=0, stack=[], locals=[None]*nl, halted=False)
|
||||
|
||||
def test_basic_add():
|
||||
"""5 + 3 = 8"""
|
||||
prog = [push_q16(5 * Q16_SCALE), push_q16(3 * Q16_SCALE), prim(Prim.ADD_SAT_Q16), halt()]
|
||||
s = run(S(), prog, 100)
|
||||
assert s.halted
|
||||
assert s.stack[0].val == 8 * Q16_SCALE, f"Got {s.stack[0].val}"
|
||||
print(" ✅ basic_add: 5 + 3 = 8")
|
||||
|
||||
def test_div_q16():
|
||||
"""3 / 5 = 0.6 in Q16_16"""
|
||||
prog = [push_q16(3 * Q16_SCALE), push_q16(5 * Q16_SCALE), prim(Prim.DIV_SAT_Q16), halt()]
|
||||
s = run(S(), prog, 100)
|
||||
expected = (3 * Q16_SCALE) // 5 # floor(0.6 * 65536) = 39321
|
||||
assert s.stack[0].val == expected, f"Got {s.stack[0].val}, expected {expected}"
|
||||
print(" ✅ div_q16: 3/5 = 0.6")
|
||||
|
||||
def test_saturation():
|
||||
"""max-1 + 2 → max"""
|
||||
prog = [push_q16(AVM_CLAMP_MAX - 1), push_q16(2), prim(Prim.ADD_SAT_Q16), halt()]
|
||||
s = run(S(), prog, 100)
|
||||
assert s.stack[0].val == AVM_CLAMP_MAX
|
||||
print(" ✅ saturation: max-1 + 2 = max")
|
||||
|
||||
def test_v6_comparison():
|
||||
cases = [(-5, -3, True), (-3, -5, False), (5, 3, False), (3, 5, True), (-1, 2, True)]
|
||||
for a, b, exp in cases:
|
||||
prog = [push_q16(a * Q16_SCALE), push_q16(b * Q16_SCALE), prim(Prim.LT_Q16), halt()]
|
||||
s = run(S(), prog, 100)
|
||||
assert s.stack[0].val == exp, f"ltQ16({a},{b}): exp {exp}, got {s.stack[0].val}"
|
||||
print(" ✅ v6_comparison: 5 cases pass")
|
||||
|
||||
def test_type_mismatch():
|
||||
prog = [push_bool(True), push_q16(Q16_SCALE), prim(Prim.ADD_SAT_Q16)]
|
||||
try:
|
||||
run(S(), prog, 100)
|
||||
return "❌ type_mismatch: should fail"
|
||||
except (TypeError, ValueError):
|
||||
print(" ✅ type_mismatch: rejected")
|
||||
|
||||
def test_stack_overflow():
|
||||
prog = [push_q16(0)] * (AVM_MAX_STACK + 1)
|
||||
try:
|
||||
run(S(), prog, 10000)
|
||||
print(" ❌ stack_overflow: should fail")
|
||||
except ValueError:
|
||||
print(" ✅ stack_overflow: rejected")
|
||||
|
||||
def test_division_by_zero():
|
||||
prog = [push_q16(Q16_SCALE), push_q16(0), prim(Prim.DIV_SAT_Q16)]
|
||||
try:
|
||||
run(S(), prog, 100)
|
||||
print(" ❌ div_by_zero: should fail")
|
||||
except (ValueError, ZeroDivisionError):
|
||||
print(" ✅ div_by_zero: rejected")
|
||||
|
||||
def test_control_flow():
|
||||
prog = [push_bool(True), jump_if(4), push_q16(0), halt(), push_q16(Q16_SCALE), halt()]
|
||||
s = run(S(), prog, 100)
|
||||
assert s.stack[0].val == Q16_SCALE
|
||||
print(" ✅ control_flow: jump_if true")
|
||||
|
||||
def test_locals():
|
||||
prog = [push_q16(42 * Q16_SCALE), store(0), load(0), halt()]
|
||||
s = run(S(1), prog, 100)
|
||||
assert s.stack[0].val == 42 * Q16_SCALE
|
||||
print(" ✅ locals: store+load")
|
||||
|
||||
def test_mul_div_rt():
|
||||
prog = [push_q16(5*Q16_SCALE), push_q16(3*Q16_SCALE), prim(Prim.MUL_SAT_Q16),
|
||||
push_q16(3*Q16_SCALE), prim(Prim.DIV_SAT_Q16), halt()]
|
||||
s = run(S(), prog, 100)
|
||||
assert s.stack[0].val == 5 * Q16_SCALE
|
||||
print(" ✅ mul_div_roundtrip: 5*3/3 = 5")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("AVM Python — Test Harness")
|
||||
print("=========================")
|
||||
for fn in [test_basic_add, test_div_q16, test_saturation, test_v6_comparison,
|
||||
test_type_mismatch, test_stack_overflow, test_division_by_zero,
|
||||
test_control_flow, test_locals, test_mul_div_rt]:
|
||||
fn()
|
||||
print("\nAll Python tests passed.")
|
||||
Loading…
Add table
Reference in a new issue