-
Notifications
You must be signed in to change notification settings - Fork 0
/
Auction.hs
95 lines (71 loc) · 4.18 KB
/
Auction.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Auction where
import Language
--- START AUCTION MODULE ---
-- Library functions
-- | return element at index
atIndex list index = Fold list (SumL (Lit (I 0))) (\e acc -> (
Case acc
(\n ->
If (IEq n index)
(Skip (SumR (e)))
(SumL (Plus n (Lit (I 1))))
)
(\_ ->
(Skip (Skip (Skip (Skip (acc)))))
)
))
-- | Returns a default value on the atIndex function
atIndexWithDefault list index def = Case (atIndex list index) (\_ -> def) (\x -> x)
-- | Some testing
atIndexTest = interpret (atIndex (Lit $ L ((I 0) ::: (I 3) ::: Nill)) (Lit (I 1))) -- Little test
-- Items:
-- 0: Chicken. Normal price: 30
-- 1: Cow. Normal price: 5000
-- 2: Cricket. Normal price: 2
-- 3: Salmon. Normal price 300
-- [ID, Quantity, price pr. item]
type AuctionOffer = TypePack (List (TypePack Int) (S (S (S Z))))
-- ID, [(quantityGt?, quantityTest), (priceGt?, priceTest)] --
type AuctionOfferCondition = TypePack ((TypePack Int), (TypePack (List (TypePack (TypePack Bool, TypePack Int)) (S (S Z)))))
type AuctionOfferConditions size = TypePack (List AuctionOfferCondition size)
testNumber isGt number test = If isGt
(IGt number test)
(ILt number test)
-- An example of just how expressive the language is.
isConditionSatisfied offer condition = let
offerId = atIndexWithDefault offer (Lit (I 0)) (Lit (I (-1)))
offerQuantity = atIndexWithDefault offer (Lit (I 1)) (Lit (I (-1)))
offerPrice = atIndexWithDefault offer (Lit (I 2)) (Lit (I (-1)))
conditionId = Fst condition
conditionQuantityGt = Fst (atIndexWithDefault (Scn condition) (Lit (I 0)) (Lit (P (B True) (I (-1)))))
conditionQuantity = Scn (atIndexWithDefault (Scn condition) (Lit (I 0)) (Lit (P (B True) (I (-1)))))
conditionPriceGt = Fst (atIndexWithDefault (Scn condition) (Lit (I 1)) (Lit (P (B True) (I (-1)))))
conditionPrice = Scn (atIndexWithDefault (Scn condition) (Lit (I 1)) (Lit (P (B True) (I (-1)))))
in
And (IEq offerId conditionId)
(And
(testNumber conditionQuantityGt offerQuantity conditionQuantity)
(testNumber conditionPriceGt offerPrice conditionPrice)
)
auctionBuyer1Conditions :: AuctionOfferConditions (S (S Z))
auctionBuyer1Conditions = L (
-- Wants to buy chicken for under 20, any quantity
(P (I 0) (L (((P (B True) (I 0))) ::: (P (B False) (I 20)) ::: Nill))) :::
-- Wants at most 5 salmon, any price
(P (I 3) (L (((P (B False) (I 6))) ::: (P (B True) (I (-1))) ::: Nill))) :::
Nill
)
isOfferAccepted offer conditions = Fold (Map conditions (\cond -> isConditionSatisfied offer cond)) (Lit (B False)) (\a b -> Or a b)
offer1 :: AuctionOffer
offer1 = L ((I 0) ::: (I 10) ::: (I 15) ::: Nill)
merchant1 = \offer -> (isOfferAccepted offer (Lit auctionBuyer1Conditions))
interpMerchant merchant offer = timedInterpret (merchant (Lit offer))
-- Merchant 2, wants to buy crickets, ALL the crickets.
merchant2 = \offer -> IEq (atIndexWithDefault offer (Lit (I 0)) (Lit (I (-1)))) (Lit (I 2))
merchants = [interpMerchant merchant1, interpMerchant merchant2]
acceptedOffer1 = map (\merchant -> merchant offer1) merchants