1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-12 14:28:08 +03:00
juvix/examples/midsquare/MidSquareHashUnrolled.jvc
Łukasz Czajka 55374ec96a
Recursion unrolling for functions (#1912)
* Depends on PR #1909 
* Closes #1750 
* Adds recursion unrolling tests on JuvixCore
* Adds a version of the mid-square hash example without the recursion
manually unrolled

For now, the recursion is always unrolled to a fixed depth (140). In the
future, we want to add a global option to override this depth, as well
as a mechanism to specify it on a per-function basis. In a more distant
future, we might want to try deriving the unrolling depth heuristically
for each function.
2023-03-24 15:05:37 +01:00

52 lines
2.4 KiB
Plaintext

-- This file implements the mid-square hashing function in JuvixCore. See:
-- https://research.cs.vt.edu/AVresearch/hashing/midsquare.php
--
-- The implementation is for hashing natural numbers with maximum 16 bits into 6
-- bits. In order to facilitate the translation to the current version of the
-- GEB backend, no recursion is used (it is manually unrolled).
--
-- `powN` is 2 ^ N
def pow0 : Int := 1;
def pow1 : Int := 2 * pow0;
def pow2 : Int := 2 * pow1;
def pow3 : Int := 2 * pow2;
def pow4 : Int := 2 * pow3;
def pow5 : Int := 2 * pow4;
def pow6 : Int := 2 * pow5;
def pow7 : Int := 2 * pow6;
def pow8 : Int := 2 * pow7;
def pow9 : Int := 2 * pow8;
def pow10 : Int := 2 * pow9;
def pow11 : Int := 2 * pow10;
def pow12 : Int := 2 * pow11;
def pow13 : Int := 2 * pow12;
def pow14 : Int := 2 * pow13;
def pow15 : Int := 2 * pow14;
def pow16 : Int := 2 * pow15;
-- `hashN` hashes a number with max N bits (i.e. smaller than 2^N) into 6 bits
-- (i.e. smaller than 64) using the mid-square algorithm.
def hash0 : Int -> Int := \(x : Int) 0;
def hash1 : Int -> Int := \(x : Int) x * x;
def hash2 : Int -> Int := \(x : Int) x * x;
def hash3 : Int -> Int := \(x : Int) x * x;
def hash4 : Int -> Int := \(x : Int) if x < pow3 then hash3 x else ((x * x) / pow1) % pow6;
def hash5 : Int -> Int := \(x : Int) if x < pow4 then hash4 x else ((x * x) / pow2) % pow6;
def hash6 : Int -> Int := \(x : Int) if x < pow5 then hash5 x else ((x * x) / pow3) % pow6;
def hash7 : Int -> Int := \(x : Int) if x < pow6 then hash6 x else ((x * x) / pow4) % pow6;
def hash8 : Int -> Int := \(x : Int) if x < pow7 then hash7 x else ((x * x) / pow5) % pow6;
def hash9 : Int -> Int := \(x : Int) if x < pow8 then hash8 x else ((x * x) / pow6) % pow6;
def hash10 : Int -> Int := \(x : Int) if x < pow9 then hash9 x else ((x * x) / pow7) % pow6;
def hash11 : Int -> Int := \(x : Int) if x < pow10 then hash10 x else ((x * x) / pow8) % pow6;
def hash12 : Int -> Int := \(x : Int) if x < pow11 then hash11 x else ((x * x) / pow9) % pow6;
def hash13 : Int -> Int := \(x : Int) if x < pow12 then hash12 x else ((x * x) / pow10) % pow6;
def hash14 : Int -> Int := \(x : Int) if x < pow13 then hash13 x else ((x * x) / pow11) % pow6;
def hash15 : Int -> Int := \(x : Int) if x < pow14 then hash14 x else ((x * x) / pow12) % pow6;
def hash16 : Int -> Int := \(x : Int) if x < pow15 then hash15 x else ((x * x) / pow13) % pow6;
def hash : Int -> Int := hash16;
hash 1367
-- result: 3