repeat<n>(a) = (x:[n]) where
if n = 1 then
x = a
else
if n - (2 * (n / 2)) = 1 then
u = repeat<n/2>(a);
x = a . u . u
else
u = repeat<n/2>(a);
x = u . u
end if
end if
end where
fulladder(a,b,c) = (s, r) where
s = (a ^ b) ^ c;
r = (a & b) + ((a ^ b) & c);
end where
adder<n>(a:[n], b:[n], c_in) = (o:[n], c_out) where
if n = 1 then
(o, c_out) = fulladder(a[0], b[0], c_in)
else
(s_n, c_n1) = fulladder(a[0], b[0], c_in);
(s_n1, c_out) = adder<n-1>(a[1..], b[1..], c_n1);
o = s_n . s_n1
end if
end where
equal<n, m>(a:[n]) = (eq) where
if n = 0 then
eq = 1
else
if m - (2 * (m / 2)) = 1 then
eq = a[0] & equal<n-1, m/2>(a[1..]);
else
eq = (not a[0]) & equal<n-1, m/2>(a[1..]);
end if
end if
end where
reg_n<n>(a:[n]) = (r:[n]) where
if n = 1 then
r = reg a[0]
else
r = (reg a[0]) . (reg_n<n-1>(a[1..]))
end if
end where
and_each<n>(a, b:[n]) = (o:[n]) where
if n = 1 then
o = b[0] and a
else
o = (b[0] and a) . and_each<n-1>(a, b[1..])
end if
end where
count_mod<n, m>(in:[n]) = (out:[n]) where
(incr, carry) = adder<n>(in, 1 . repeat<n-1>(0), 0);
neq = not (equal<n, m>(incr));
out = and_each<n>(neq, incr)
end where
main() = (out:[4],next:[4]) where
next = count_mod<4, 12>(out);
out = reg_n<4>(next)
end where