From c9ed8869254dcd01f40a7ff9e8a31be0c4b2ec66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Hillerstr=C3=B6m?= Date: Fri, 19 Jul 2024 11:42:22 +0200 Subject: [PATCH 1/2] A silly example program This is a little fun and silly example program which computes and renders the Sierpinski triangle using bitwise-and. ```links links> sierpinski(); ******************************** * * * * * * * * * * * * * * * * ** ** ** ** ** ** ** ** * * * * * * * * **** **** **** **** * * * * * * * * ** ** ** ** * * * * ******** ******** * * * * * * * * ** ** ** ** * * * * **** **** * * * * ** ** * * **************** * * * * * * * * ** ** ** ** * * * * **** **** * * * * ** ** * * ******** * * * * ** ** * * **** * * ** * () : () ``` --- examples/sierpinski_bits.links | 66 ++++++++++++++++++++++++++++++++++ tests/typecheck_examples.tests | 4 +++ 2 files changed, 70 insertions(+) create mode 100644 examples/sierpinski_bits.links diff --git a/examples/sierpinski_bits.links b/examples/sierpinski_bits.links new file mode 100644 index 000000000..22f21f860 --- /dev/null +++ b/examples/sierpinski_bits.links @@ -0,0 +1,66 @@ +# Computing the Sierpinski triangle using bit twiddling. +# Adapted from https://www.johndcook.com/blog/2019/11/26/fractal-via-bit-twiddling/ + +# First things first, we do not have bit twiddling operations in +# Links. So we need to implement them. Fortunately, we require only +# the bitwise-and operation. + +# We represent a bitvector as a list of booleans. +typename Bits = [Bool]; + +# The following function zips two bitvectors together, padding with +# zeroes (false) if needed. +sig zipbits : ((Bool, Bool) ~e~> Bool, Bits, Bits) ~e~> Bits +fun zipbits(f, xs, ys) { + switch ((xs, ys)) { + case ([], []) -> [] + case (x :: xs, []) -> f(x, false) :: zipbits(f, xs, []) + case ([], y :: ys) -> f(y, false) :: zipbits(f, [], ys) + case (x :: xs, y :: ys) -> f(x, y) :: zipbits(f, xs, ys) + } +} + +# Computes the bitwise-and of two bit vectors. +sig band : (Bits, Bits) ~> Bits +fun band(bs, bs') { + zipbits(fun(b, b') { b && b' }, bs, bs') +} + +# Conversions between Int <-> Bits +sig pow2 : (Int) ~> Int +fun pow2(n) { + if (n == 0) 1 + else 2 * pow2(n-1) +} + +sig bitsToInt : (Bits) ~> Int +fun bitsToInt(bs) { + var xs = mapi(fun(b, i) { + if (b) pow2(i) else 0 + }, bs); + sum(xs) +} + +sig intToBits : (Int) ~> Bits +fun intToBits(i) { + fun loop(i) { + if (i > 0) (mod(i, 2) == 1) :: intToBits(i / 2) + else [] + } + loop(i) +} + +# Now we can compute and render the Sierpinski triangle. We print an +# asterisk (*) whenever the bitwise-and of i and j is zero. +sig sierpinski : () ~> () +fun sierpinski() { + var range = [0..31]; + iter(fun(i) { + var bs = intToBits(i); + iter(fun(j) { + var bs' = intToBits(j); + print(if (all(not, band(bs, bs'))) "*" else " ") + }, range); + println("") + }, range) +} diff --git a/tests/typecheck_examples.tests b/tests/typecheck_examples.tests index 4e968ad1f..5fce6aa6a 100644 --- a/tests/typecheck_examples.tests +++ b/tests/typecheck_examples.tests @@ -669,6 +669,10 @@ Typecheck example file examples/validate.links examples/validate.links filemode : true +Typecheck example file examples/sierpinski-bits.links +examples/sierpinski-bits.links +filemode : true + Typecheck example file examples/webserver/buttons.links examples/webserver/buttons.links filemode : true From 84e9a94653a09a6a18554f26c65c899465353515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Hillerstr=C3=B6m?= Date: Mon, 29 Jul 2024 11:12:21 +0200 Subject: [PATCH 2/2] Replace '-' by '_'. --- tests/typecheck_examples.tests | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/typecheck_examples.tests b/tests/typecheck_examples.tests index 5fce6aa6a..8e8ac49a5 100644 --- a/tests/typecheck_examples.tests +++ b/tests/typecheck_examples.tests @@ -669,8 +669,8 @@ Typecheck example file examples/validate.links examples/validate.links filemode : true -Typecheck example file examples/sierpinski-bits.links -examples/sierpinski-bits.links +Typecheck example file examples/sierpinski_bits.links +examples/sierpinski_bits.links filemode : true Typecheck example file examples/webserver/buttons.links