Commit 7f15188a authored by Yiannis Tsiouris's avatar Yiannis Tsiouris

Implement the Credit module

parent 2a9b53da
--
-- orbit-int credits (for checking termination of orbit computation)
--
module Credit( credit
, credit_atomic
, debit_atomic
, debit_atomic_nz
, zero
, one
, is_zero
, is_one) where
-- An *atomic credit* is represented as a non-negative integer k;
-- it stands for the credit 1/{2^k}.
--
-- A *credit* is represented as list of non-negative integers, sorted in
-- strict descending order; it represents the sum of atomic credits
-- represented by the integers on the list, where zero credit is
-- represented by the empty list. The maximally possible credit, 1,
-- is represented by [0].
-- credit_atomic(K, C) adds the atomic credit 1/{2^K} to the credit C.
credit_atomic :: Int -> [Int] -> [Int]
credit_atomic k [] = [k]
credit_atomic k (c : cs) | k > c = k : c : cs
| k == c = credit_atomic (k - 1) cs
| otherwise = c : credit_atomic k cs
-- credit(C1, C2) returns a list representing the sum of the credit
-- represented by the lists C1 and C2.
credit :: [Int] -> [Int] -> [Int]
credit c1 c2 = foldl (flip credit_atomic) c2 c1
-- debit_atomic(C) returns a pair {K',C'} where K' is an integer
-- representing some atomic credit and C' is a list of integers representing
-- some credit (which may be zero) such that the sum of the credits
-- represented by K' and C' equals the credit represented by C.
-- Precondition: C must represent non-zero credit.
debit_atomic :: [Int] -> (Int, [Int])
debit_atomic (c : cs) = (c, cs) -- debit smallest unit of credit
-- debit_atomic_nz(C) returns a pair {K',C'} where K' is an integer
-- representing some atomic credit and C' is a list of integers representing
-- some non-zero credit such that the sum of the credits
-- represented by K' and C' equals the credit represented by C.
-- Precondition: C must represent non-zero credit.
debit_atomic_nz :: [Int] -> (Int, [Int])
debit_atomic_nz [c] = (c + 1, [c + 1]) -- debit half the credit
debit_atomic_nz (c : cs) = (c, cs) -- debit smallest unit of credit;
-- case only applies if Cs non-empty
-- zero/0 produces zero credit.
zero :: [Int]
zero = []
-- one/0 produces credit one.
one :: [Int]
one = [0]
-- is_zero/1 tests whether its argument represents zero credit.
is_zero :: [Int] -> Bool
is_zero [] = True
is_zero _ = False
-- is_one/1 tests whether its argument represents maximal credit 1.
is_one :: [Int] -> Bool
is_one [0] = True
is_one _ = False
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment