Skip to content

Instantly share code, notes, and snippets.

@JonasLoos
Last active November 8, 2024 03:52
Show Gist options
  • Save JonasLoos/af125f50fc13c6cdbbee656e18213060 to your computer and use it in GitHub Desktop.
Save JonasLoos/af125f50fc13c6cdbbee656e18213060 to your computer and use it in GitHub Desktop.
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::Instant;
// Type Definitions
type Tag = u8;
type Lab = u32;
type Loc = u32;
type Term = u64;
// Constants
const DP0: Tag = 0x00;
const DP1: Tag = 0x01;
const VAR: Tag = 0x02;
const APP: Tag = 0x03;
const ERA: Tag = 0x04;
const LAM: Tag = 0x05;
const SUP: Tag = 0x06;
const SUB: Tag = 0x07;
const VOID: Term = 0x00000000000000;
// Heap Structure
struct Heap {
stk: Box<[Term]>,
mem: Box<[AtomicU64]>,
ini: AtomicU64,
end: AtomicU64,
itr: AtomicU64,
}
impl Heap {
fn new() -> Self {
let stk_size = (1u64 << 32) as usize; // 4,294,967,296 elements
let mem_size = (1u64 << 32) as usize; // 4,294,967,296 elements
let stk = vec![0u64; stk_size].into_boxed_slice();
let mem = vec![0u64; mem_size].into_boxed_slice();
let mem = unsafe { std::mem::transmute::<Box<[u64]>, Box<[AtomicU64]>>(mem) };
let ini = AtomicU64::new(0);
let end = AtomicU64::new(1);
let itr = AtomicU64::new(0);
Heap { stk, mem, ini, end, itr }
}
fn new_term(tag: Tag, lab: Lab, loc: Loc) -> Term {
let tag_enc = tag as Term;
let lab_enc = (lab as Term) << 8;
let loc_enc = (loc as Term) << 32;
tag_enc | lab_enc | loc_enc
}
fn get_tag(x: Term) -> Tag {
(x & 0xFF) as Tag
}
fn get_lab(x: Term) -> Lab {
((x >> 8) & 0xFFFFFF) as Lab
}
fn get_loc(x: Term) -> Loc {
((x >> 32) & 0xFFFFFFFF) as Loc
}
fn get_key(term: Term) -> Loc {
match Heap::get_tag(term) {
VAR => Heap::get_loc(term) + 0,
DP0 => Heap::get_loc(term) + 0,
DP1 => Heap::get_loc(term) + 1,
_ => 0,
}
}
fn get_ini(&self) -> Loc {
self.ini.load(Ordering::Relaxed) as Loc
}
fn get_end(&self) -> Loc {
self.end.load(Ordering::Relaxed) as Loc
}
fn get_itr(&self) -> Loc {
self.itr.load(Ordering::Relaxed) as Loc
}
fn set_ini(&self, value: Loc) {
self.ini.store(value as u64, Ordering::Relaxed);
}
fn set_end(&self, value: Loc) {
self.end.store(value as u64, Ordering::Relaxed);
}
fn set_itr(&self, value: Loc) {
self.itr.store(value as u64, Ordering::Relaxed);
}
fn swap(&self, loc: Loc, term: Term) -> Term {
self.mem[loc as usize].swap(term, Ordering::Relaxed)
}
fn got(&self, loc: Loc) -> Term {
self.mem[loc as usize].load(Ordering::Relaxed)
}
fn set(&self, loc: Loc, term: Term) {
self.mem[loc as usize].store(term, Ordering::Relaxed);
}
fn take(&self, loc: Loc) -> Term {
self.swap(loc, VOID)
}
fn alloc_node(&self, arity: Loc) -> Loc {
self.end.fetch_add(arity as u64, Ordering::Relaxed) as Loc
}
fn inc_itr(&self) -> Loc {
self.itr.fetch_add(1, Ordering::Relaxed) as Loc
}
fn print_tag(tag: Tag) {
match tag {
SUP => print!("SUP"),
VAR => print!("VAR"),
DP0 => print!("DP0"),
DP1 => print!("DP1"),
APP => print!("APP"),
ERA => print!("ERA"),
LAM => print!("LAM"),
SUB => print!("SUB"),
_ => print!("???"),
}
}
fn print_term(&self, term: Term) {
print!("new_term(");
Heap::print_tag(Self::get_tag(term));
print!(",0x{:06x},0x{:09x})", Self::get_lab(term), Self::get_loc(term));
}
fn print_heap(&self) {
let end = self.get_end();
for i in 0..end {
let term = self.got(i);
if term != 0 {
print!("set(heap, 0x{:09x}, ", i);
self.print_term(term);
println!(");");
}
}
}
// Evaluation Functions
// reduce_app_era
fn reduce_app_era(&self, _app: Term, era: Term) -> Term {
self.inc_itr();
era
}
// reduce_app_lam
fn reduce_app_lam(&self, app: Term, lam: Term) -> Term {
self.inc_itr();
let app_loc = Heap::get_loc(app);
let lam_loc = Heap::get_loc(lam);
let arg = self.got(app_loc + 1);
let bod = self.got(lam_loc + 1);
self.set(lam_loc + 0, arg);
bod
}
// reduce_app_sup
fn reduce_app_sup(&self, app: Term, sup: Term) -> Term {
self.inc_itr();
let app_loc = Heap::get_loc(app);
let sup_loc = Heap::get_loc(sup);
let arg = self.got(app_loc + 1);
let tm0 = self.got(sup_loc);
let tm1 = self.got(sup_loc + 1);
let du0 = self.alloc_node(3);
let su0 = self.alloc_node(2);
let ap0 = self.alloc_node(2);
let ap1 = self.alloc_node(2);
self.set(du0 + 0, Heap::new_term(SUB, 0, 0));
self.set(du0 + 1, Heap::new_term(SUB, 0, 0));
self.set(du0 + 2, arg);
self.set(ap0 + 0, tm0);
self.set(ap0 + 1, Heap::new_term(DP0, 0, du0));
self.set(ap1 + 0, tm1);
self.set(ap1 + 1, Heap::new_term(DP1, 0, du0));
self.set(su0 + 0, Heap::new_term(APP, 0, ap0));
self.set(su0 + 1, Heap::new_term(APP, 0, ap1));
Heap::new_term(SUP, 0, su0)
}
// reduce_dup_era
fn reduce_dup_era(&self, dup: Term, era: Term) -> Term {
self.inc_itr();
let dup_loc = Heap::get_loc(dup);
let dup_num = if Heap::get_tag(dup) == DP0 { 0 } else { 1 };
self.set(dup_loc + 0, era);
self.set(dup_loc + 1, era);
self.got(dup_loc + dup_num)
}
// reduce_dup_lam
fn reduce_dup_lam(&self, dup: Term, lam: Term) -> Term {
self.inc_itr();
let dup_loc = Heap::get_loc(dup);
let dup_num = if Heap::get_tag(dup) == DP0 { 0 } else { 1 };
let lam_loc = Heap::get_loc(lam);
let bod = self.got(lam_loc + 1);
let du0 = self.alloc_node(3);
let lm0 = self.alloc_node(2);
let lm1 = self.alloc_node(2);
let su0 = self.alloc_node(2);
self.set(du0 + 0, Heap::new_term(SUB, 0, 0));
self.set(du0 + 1, Heap::new_term(SUB, 0, 0));
self.set(du0 + 2, bod);
self.set(lm0 + 0, Heap::new_term(SUB, 0, 0));
self.set(lm0 + 1, Heap::new_term(DP0, 0, du0));
self.set(lm1 + 0, Heap::new_term(SUB, 0, 0));
self.set(lm1 + 1, Heap::new_term(DP1, 0, du0));
self.set(su0 + 0, Heap::new_term(VAR, 0, lm0));
self.set(su0 + 1, Heap::new_term(VAR, 0, lm1));
self.set(dup_loc + 0, Heap::new_term(LAM, 0, lm0));
self.set(dup_loc + 1, Heap::new_term(LAM, 0, lm1));
self.set(lam_loc + 0, Heap::new_term(SUP, 0, su0));
self.got(dup_loc + dup_num)
}
// reduce_dup_sup
fn reduce_dup_sup(&self, dup: Term, sup: Term) -> Term {
self.inc_itr();
let dup_loc = Heap::get_loc(dup);
let dup_num = if Heap::get_tag(dup) == DP0 { 0 } else { 1 };
let sup_loc = Heap::get_loc(sup);
let tm0 = self.got(sup_loc);
let tm1 = self.got(sup_loc + 1);
self.set(dup_loc + 0, tm0);
self.set(dup_loc + 1, tm1);
self.got(dup_loc + dup_num)
}
// Reduce Function
fn reduce(&self, term: Term) -> Term {
let mut path: Vec<Term> = Vec::new();
let mut next = term;
loop {
let tag = Heap::get_tag(next);
let _lab = Heap::get_lab(next);
let loc = Heap::get_loc(next);
match tag {
APP => {
path.push(next);
next = self.got(loc);
continue;
}
DP0 | DP1 => {
let key = Heap::get_key(next);
let sub = self.got(key);
if Heap::get_tag(sub) == SUB {
path.push(next);
next = self.got(loc + 2);
continue;
} else {
next = sub;
continue;
}
}
VAR => {
let key = Heap::get_key(next);
let sub = self.got(key);
if Heap::get_tag(sub) == SUB {
break;
} else {
next = sub;
continue;
}
}
_ => {
if path.is_empty() {
break;
} else {
let prev = path.pop().unwrap();
let ptag = Heap::get_tag(prev);
let _plab = Heap::get_lab(prev);
let _ploc = Heap::get_loc(prev);
match ptag {
APP => {
match tag {
ERA => {
next = self.reduce_app_era(prev, next);
continue;
}
LAM => {
next = self.reduce_app_lam(prev, next);
continue;
}
SUP => {
next = self.reduce_app_sup(prev, next);
continue;
}
_ => {}
}
}
DP0 | DP1 => {
match tag {
ERA => {
next = self.reduce_dup_era(prev, next);
continue;
}
LAM => {
next = self.reduce_dup_lam(prev, next);
continue;
}
SUP => {
next = self.reduce_dup_sup(prev, next);
continue;
}
_ => {}
}
}
_ => {}
}
}
}
}
if path.is_empty() {
break;
} else {
let host = path.pop().unwrap();
let htag = Heap::get_tag(host);
let _hlab = Heap::get_lab(host);
let hloc = Heap::get_loc(host);
match htag {
APP => {
self.set(hloc, next);
continue;
}
DP0 | DP1 => {
self.set(hloc + 2, next);
continue;
}
_ => {
next = 0;
break;
}
}
}
}
if path.is_empty() {
next
} else {
0
}
}
// Normal Function
fn normal(&self, term: Term) -> Term {
let wnf = self.reduce(term);
let tag = Heap::get_tag(wnf);
let _lab = Heap::get_lab(wnf);
let loc = Heap::get_loc(wnf);
match tag {
APP => {
let fun = self.got(loc);
let fun = self.normal(fun);
let arg = self.got(loc + 1);
let arg = self.normal(arg);
self.set(loc, fun);
self.set(loc + 1, arg);
wnf
}
LAM => {
let bod = self.got(loc + 1);
let bod = self.normal(bod);
self.set(loc + 1, bod);
wnf
}
SUP => {
let tm0 = self.got(loc);
let tm0 = self.normal(tm0);
let tm1 = self.got(loc + 1);
let tm1 = self.normal(tm1);
self.set(loc, tm0);
self.set(loc + 1, tm1);
wnf
}
DP0 | DP1 => {
let val = self.got(loc + 2);
let val = self.normal(val);
self.set(loc + 2, val);
wnf
}
_ => wnf,
}
}
}
// Inject P24 Function
fn inject_P24(heap: &Heap) {
heap.set_ini(0x000000000);
heap.set_end(0x0000000f1);
heap.set_itr(0x000000000);
heap.set(0x000000000, Heap::new_term(APP, 0x000000, 0x000000001));
heap.set(0x000000001, Heap::new_term(APP, 0x000000, 0x000000003));
heap.set(0x000000002, Heap::new_term(LAM, 0x000000, 0x0000000ed));
heap.set(0x000000003, Heap::new_term(LAM, 0x000000, 0x000000005));
heap.set(0x000000004, Heap::new_term(LAM, 0x000000, 0x0000000df));
heap.set(0x000000005, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000006, Heap::new_term(LAM, 0x000000, 0x0000000d9));
heap.set(0x000000007, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000008, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000009, Heap::new_term(VAR, 0x000000, 0x000000005));
heap.set(0x00000000a, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000000b, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000000c, Heap::new_term(LAM, 0x000000, 0x00000000d));
heap.set(0x00000000d, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000000e, Heap::new_term(APP, 0x000000, 0x00000000f));
heap.set(0x00000000f, Heap::new_term(DP0, 0x000000, 0x000000007));
heap.set(0x000000010, Heap::new_term(APP, 0x000000, 0x000000011));
heap.set(0x000000011, Heap::new_term(DP1, 0x000000, 0x000000007));
heap.set(0x000000012, Heap::new_term(VAR, 0x000000, 0x00000000d));
heap.set(0x000000013, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000014, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000015, Heap::new_term(LAM, 0x000000, 0x000000016));
heap.set(0x000000016, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000017, Heap::new_term(APP, 0x000000, 0x000000018));
heap.set(0x000000018, Heap::new_term(DP0, 0x000000, 0x00000000a));
heap.set(0x000000019, Heap::new_term(APP, 0x000000, 0x00000001a));
heap.set(0x00000001a, Heap::new_term(DP1, 0x000000, 0x00000000a));
heap.set(0x00000001b, Heap::new_term(VAR, 0x000000, 0x000000016));
heap.set(0x00000001c, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000001d, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000001e, Heap::new_term(LAM, 0x000000, 0x00000001f));
heap.set(0x00000001f, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000020, Heap::new_term(APP, 0x000000, 0x000000021));
heap.set(0x000000021, Heap::new_term(DP0, 0x000000, 0x000000013));
heap.set(0x000000022, Heap::new_term(APP, 0x000000, 0x000000023));
heap.set(0x000000023, Heap::new_term(DP1, 0x000000, 0x000000013));
heap.set(0x000000024, Heap::new_term(VAR, 0x000000, 0x00000001f));
heap.set(0x000000025, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000026, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000027, Heap::new_term(LAM, 0x000000, 0x000000028));
heap.set(0x000000028, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000029, Heap::new_term(APP, 0x000000, 0x00000002a));
heap.set(0x00000002a, Heap::new_term(DP0, 0x000000, 0x00000001c));
heap.set(0x00000002b, Heap::new_term(APP, 0x000000, 0x00000002c));
heap.set(0x00000002c, Heap::new_term(DP1, 0x000000, 0x00000001c));
heap.set(0x00000002d, Heap::new_term(VAR, 0x000000, 0x000000028));
heap.set(0x00000002e, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000002f, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000030, Heap::new_term(LAM, 0x000000, 0x000000031));
heap.set(0x000000031, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000032, Heap::new_term(APP, 0x000000, 0x000000033));
heap.set(0x000000033, Heap::new_term(DP0, 0x000000, 0x000000025));
heap.set(0x000000034, Heap::new_term(APP, 0x000000, 0x000000035));
heap.set(0x000000035, Heap::new_term(DP1, 0x000000, 0x000000025));
heap.set(0x000000036, Heap::new_term(VAR, 0x000000, 0x000000031));
heap.set(0x000000037, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000038, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000039, Heap::new_term(LAM, 0x000000, 0x00000003a));
heap.set(0x00000003a, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000003b, Heap::new_term(APP, 0x000000, 0x00000003c));
heap.set(0x00000003c, Heap::new_term(DP0, 0x000000, 0x00000002e));
heap.set(0x00000003d, Heap::new_term(APP, 0x000000, 0x00000003e));
heap.set(0x00000003e, Heap::new_term(DP1, 0x000000, 0x00000002e));
heap.set(0x00000003f, Heap::new_term(VAR, 0x000000, 0x00000003a));
heap.set(0x000000040, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000041, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000042, Heap::new_term(LAM, 0x000000, 0x000000043));
heap.set(0x000000043, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000044, Heap::new_term(APP, 0x000000, 0x000000045));
heap.set(0x000000045, Heap::new_term(DP0, 0x000000, 0x000000037));
heap.set(0x000000046, Heap::new_term(APP, 0x000000, 0x000000047));
heap.set(0x000000047, Heap::new_term(DP1, 0x000000, 0x000000037));
heap.set(0x000000048, Heap::new_term(VAR, 0x000000, 0x000000043));
heap.set(0x000000049, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000004a, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000004b, Heap::new_term(LAM, 0x000000, 0x00000004c));
heap.set(0x00000004c, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000004d, Heap::new_term(APP, 0x000000, 0x00000004e));
heap.set(0x00000004e, Heap::new_term(DP0, 0x000000, 0x000000040));
heap.set(0x00000004f, Heap::new_term(APP, 0x000000, 0x000000050));
heap.set(0x000000050, Heap::new_term(DP1, 0x000000, 0x000000040));
heap.set(0x000000051, Heap::new_term(VAR, 0x000000, 0x00000004c));
heap.set(0x000000052, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000053, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000054, Heap::new_term(LAM, 0x000000, 0x000000055));
heap.set(0x000000055, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000056, Heap::new_term(APP, 0x000000, 0x000000057));
heap.set(0x000000057, Heap::new_term(DP0, 0x000000, 0x000000049));
heap.set(0x000000058, Heap::new_term(APP, 0x000000, 0x000000059));
heap.set(0x000000059, Heap::new_term(DP1, 0x000000, 0x000000049));
heap.set(0x00000005a, Heap::new_term(VAR, 0x000000, 0x000000055));
heap.set(0x00000005b, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000005c, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000005d, Heap::new_term(LAM, 0x000000, 0x00000005e));
heap.set(0x00000005e, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000005f, Heap::new_term(APP, 0x000000, 0x000000060));
heap.set(0x000000060, Heap::new_term(DP0, 0x000000, 0x000000052));
heap.set(0x000000061, Heap::new_term(APP, 0x000000, 0x000000062));
heap.set(0x000000062, Heap::new_term(DP1, 0x000000, 0x000000052));
heap.set(0x000000063, Heap::new_term(VAR, 0x000000, 0x00000005e));
heap.set(0x000000064, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000065, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000066, Heap::new_term(LAM, 0x000000, 0x000000067));
heap.set(0x000000067, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000068, Heap::new_term(APP, 0x000000, 0x000000069));
heap.set(0x000000069, Heap::new_term(DP0, 0x000000, 0x00000005b));
heap.set(0x00000006a, Heap::new_term(APP, 0x000000, 0x00000006b));
heap.set(0x00000006b, Heap::new_term(DP1, 0x000000, 0x00000005b));
heap.set(0x00000006c, Heap::new_term(VAR, 0x000000, 0x000000067));
heap.set(0x00000006d, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000006e, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000006f, Heap::new_term(LAM, 0x000000, 0x000000070));
heap.set(0x000000070, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000071, Heap::new_term(APP, 0x000000, 0x000000072));
heap.set(0x000000072, Heap::new_term(DP0, 0x000000, 0x000000064));
heap.set(0x000000073, Heap::new_term(APP, 0x000000, 0x000000074));
heap.set(0x000000074, Heap::new_term(DP1, 0x000000, 0x000000064));
heap.set(0x000000075, Heap::new_term(VAR, 0x000000, 0x000000070));
heap.set(0x000000076, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000077, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000078, Heap::new_term(LAM, 0x000000, 0x000000079));
heap.set(0x000000079, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000007a, Heap::new_term(APP, 0x000000, 0x00000007b));
heap.set(0x00000007b, Heap::new_term(DP0, 0x000000, 0x00000006d));
heap.set(0x00000007c, Heap::new_term(APP, 0x000000, 0x00000007d));
heap.set(0x00000007d, Heap::new_term(DP1, 0x000000, 0x00000006d));
heap.set(0x00000007e, Heap::new_term(VAR, 0x000000, 0x000000079));
heap.set(0x00000007f, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000080, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000081, Heap::new_term(LAM, 0x000000, 0x000000082));
heap.set(0x000000082, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000083, Heap::new_term(APP, 0x000000, 0x000000084));
heap.set(0x000000084, Heap::new_term(DP0, 0x000000, 0x000000076));
heap.set(0x000000085, Heap::new_term(APP, 0x000000, 0x000000086));
heap.set(0x000000086, Heap::new_term(DP1, 0x000000, 0x000000076));
heap.set(0x000000087, Heap::new_term(VAR, 0x000000, 0x000000082));
heap.set(0x000000088, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000089, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000008a, Heap::new_term(LAM, 0x000000, 0x00000008b));
heap.set(0x00000008b, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000008c, Heap::new_term(APP, 0x000000, 0x00000008d));
heap.set(0x00000008d, Heap::new_term(DP0, 0x000000, 0x00000007f));
heap.set(0x00000008e, Heap::new_term(APP, 0x000000, 0x00000008f));
heap.set(0x00000008f, Heap::new_term(DP1, 0x000000, 0x00000007f));
heap.set(0x000000090, Heap::new_term(VAR, 0x000000, 0x00000008b));
heap.set(0x000000091, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000092, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000093, Heap::new_term(LAM, 0x000000, 0x000000094));
heap.set(0x000000094, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x000000095, Heap::new_term(APP, 0x000000, 0x000000096));
heap.set(0x000000096, Heap::new_term(DP0, 0x000000, 0x000000088));
heap.set(0x000000097, Heap::new_term(APP, 0x000000, 0x000000098));
heap.set(0x000000098, Heap::new_term(DP1, 0x000000, 0x000000088));
heap.set(0x000000099, Heap::new_term(VAR, 0x000000, 0x000000094));
heap.set(0x00000009a, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000009b, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000009c, Heap::new_term(LAM, 0x000000, 0x00000009d));
heap.set(0x00000009d, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x00000009e, Heap::new_term(APP, 0x000000, 0x00000009f));
heap.set(0x00000009f, Heap::new_term(DP0, 0x000000, 0x000000091));
heap.set(0x0000000a0, Heap::new_term(APP, 0x000000, 0x0000000a1));
heap.set(0x0000000a1, Heap::new_term(DP1, 0x000000, 0x000000091));
heap.set(0x0000000a2, Heap::new_term(VAR, 0x000000, 0x00000009d));
heap.set(0x0000000a3, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000a4, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000a5, Heap::new_term(LAM, 0x000000, 0x0000000a6));
heap.set(0x0000000a6, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000a7, Heap::new_term(APP, 0x000000, 0x0000000a8));
heap.set(0x0000000a8, Heap::new_term(DP0, 0x000000, 0x00000009a));
heap.set(0x0000000a9, Heap::new_term(APP, 0x000000, 0x0000000aa));
heap.set(0x0000000aa, Heap::new_term(DP1, 0x000000, 0x00000009a));
heap.set(0x0000000ab, Heap::new_term(VAR, 0x000000, 0x0000000a6));
heap.set(0x0000000ac, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000ad, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000ae, Heap::new_term(LAM, 0x000000, 0x0000000af));
heap.set(0x0000000af, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000b0, Heap::new_term(APP, 0x000000, 0x0000000b1));
heap.set(0x0000000b1, Heap::new_term(DP0, 0x000000, 0x0000000a3));
heap.set(0x0000000b2, Heap::new_term(APP, 0x000000, 0x0000000b3));
heap.set(0x0000000b3, Heap::new_term(DP1, 0x000000, 0x0000000a3));
heap.set(0x0000000b4, Heap::new_term(VAR, 0x000000, 0x0000000af));
heap.set(0x0000000b5, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000b6, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000b7, Heap::new_term(LAM, 0x000000, 0x0000000b8));
heap.set(0x0000000b8, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000b9, Heap::new_term(APP, 0x000000, 0x0000000ba));
heap.set(0x0000000ba, Heap::new_term(DP0, 0x000000, 0x0000000ac));
heap.set(0x0000000bb, Heap::new_term(APP, 0x000000, 0x0000000bc));
heap.set(0x0000000bc, Heap::new_term(DP1, 0x000000, 0x0000000ac));
heap.set(0x0000000bd, Heap::new_term(VAR, 0x000000, 0x0000000b8));
heap.set(0x0000000be, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000bf, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000c0, Heap::new_term(LAM, 0x000000, 0x0000000c1));
heap.set(0x0000000c1, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000c2, Heap::new_term(APP, 0x000000, 0x0000000c3));
heap.set(0x0000000c3, Heap::new_term(DP0, 0x000000, 0x0000000b5));
heap.set(0x0000000c4, Heap::new_term(APP, 0x000000, 0x0000000c5));
heap.set(0x0000000c5, Heap::new_term(DP1, 0x000000, 0x0000000b5));
heap.set(0x0000000c6, Heap::new_term(VAR, 0x000000, 0x0000000c1));
heap.set(0x0000000c7, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000c8, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000c9, Heap::new_term(LAM, 0x000000, 0x0000000ca));
heap.set(0x0000000ca, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000cb, Heap::new_term(APP, 0x000000, 0x0000000cc));
heap.set(0x0000000cc, Heap::new_term(DP0, 0x000000, 0x0000000be));
heap.set(0x0000000cd, Heap::new_term(APP, 0x000000, 0x0000000ce));
heap.set(0x0000000ce, Heap::new_term(DP1, 0x000000, 0x0000000be));
heap.set(0x0000000cf, Heap::new_term(VAR, 0x000000, 0x0000000ca));
heap.set(0x0000000d0, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000d1, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000d2, Heap::new_term(LAM, 0x000000, 0x0000000d3));
heap.set(0x0000000d3, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000d4, Heap::new_term(APP, 0x000000, 0x0000000d5));
heap.set(0x0000000d5, Heap::new_term(DP0, 0x000000, 0x0000000c7));
heap.set(0x0000000d6, Heap::new_term(APP, 0x000000, 0x0000000d7));
heap.set(0x0000000d7, Heap::new_term(DP1, 0x000000, 0x0000000c7));
heap.set(0x0000000d8, Heap::new_term(VAR, 0x000000, 0x0000000d3));
heap.set(0x0000000d9, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000da, Heap::new_term(APP, 0x000000, 0x0000000db));
heap.set(0x0000000db, Heap::new_term(DP0, 0x000000, 0x0000000d0));
heap.set(0x0000000dc, Heap::new_term(APP, 0x000000, 0x0000000dd));
heap.set(0x0000000dd, Heap::new_term(DP1, 0x000000, 0x0000000d0));
heap.set(0x0000000de, Heap::new_term(VAR, 0x000000, 0x0000000d9));
heap.set(0x0000000df, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000e0, Heap::new_term(APP, 0x000000, 0x0000000e1));
heap.set(0x0000000e1, Heap::new_term(APP, 0x000000, 0x0000000e3));
heap.set(0x0000000e2, Heap::new_term(LAM, 0x000000, 0x0000000e9));
heap.set(0x0000000e3, Heap::new_term(VAR, 0x000000, 0x0000000df));
heap.set(0x0000000e4, Heap::new_term(LAM, 0x000000, 0x0000000e5));
heap.set(0x0000000e5, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000e6, Heap::new_term(LAM, 0x000000, 0x0000000e7));
heap.set(0x0000000e7, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000e8, Heap::new_term(VAR, 0x000000, 0x0000000e7));
heap.set(0x0000000e9, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000ea, Heap::new_term(LAM, 0x000000, 0x0000000eb));
heap.set(0x0000000eb, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000ec, Heap::new_term(VAR, 0x000000, 0x0000000e9));
heap.set(0x0000000ed, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000ee, Heap::new_term(LAM, 0x000000, 0x0000000ef));
heap.set(0x0000000ef, Heap::new_term(SUB, 0x000000, 0x000000000));
heap.set(0x0000000f0, Heap::new_term(VAR, 0x000000, 0x0000000ed));
}
fn main() {
let heap = Heap::new();
inject_P24(&heap);
let start = Instant::now();
// Normalize and get interaction count
let root = heap.got(0);
heap.normal(root);
let duration = start.elapsed();
println!("Itrs: {}", heap.get_itr());
println!("Size: {} nodes", heap.get_end());
println!(
"Time: {:.2} milliseconds",
duration.as_secs_f64() * 1000.0
);
println!(
"MIPS: {:.2}",
(heap.get_itr() as f64 / 1_000_000.0) / duration.as_secs_f64()
);
// Heap memory is automatically freed when it goes out of scope
}
@JonasLoos
Copy link
Author

compiled with

rustc HVML.rs -C opt-level=3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment