(* Auction Theory Toolbox (http://formare.github.io/auctions/) Authors: * Manfred Kerber * Christoph Lange * Colin Rowat * Marco B. Caminati Dually licenced under * Creative Commons Attribution (CC-BY) 3.0 * ISC License (1-clause BSD License) See LICENSE file for details (Rationale for this dual licence: http://arxiv.org/abs/1107.3212) *) header {* Combinatorial Auctions *} theory CombinatorialAuction imports Complex_Main Vectors Partitions RelationProperties begin section {* Types *} type_synonym participant = index type_synonym goods = "nat set" (* CL: actually we'd prefer "'a set", as we really don't care about the type *) type_synonym price = real (* CL: Keeping old initial vector-based bid implementation (suitable for multiple items per good and fractions of items) for reference. (* one participant's bid on a set of goods *) definition b :: "participant \ goods \ nat" where "b i y = (\ x \ y . x)" text{* convenience type synonyms for most of the basic concepts we are dealing with *} type_synonym endowment = "nat vector" (* conceptually: good \ quantity *) type_synonym endowment_subset = "nat vector" (* conceptually the same, but \ endowment *) (* A single participant ascribes real values to subsets of the endowment. *) type_synonym valuation = "endowment_subset \ real" type_synonym valuations = "valuation vector" type_synonym bid = "endowment_subset \ real" (* A well-formed bid is non-negative for each “subset” of the endowment, i.e. each vector s that is component-wise 0 \ s \ x0. *) definition bid :: "bid \ goods \ endowment \ bool" where "bid b K x0 \ (\ s . non_negative_real_vector K s \ vector_le K s x0 \ b s \ 0)" type_synonym allocation = "participant \ endowment_subset" type_synonym payments = "real vector" *) type_synonym bids = "participant \ goods \ price" type_synonym allocation_rel = "((goods \ participant) set)" (* CL: goods set not necessary as the function-as-relation-as-set representation carries its own domain :-) *) type_synonym payments = "participant \ price" (* CL: probably not needed, neither for close-to-paper nor for computable version type_synonym allocation_fun = "(goods set) \ (goods \ participant)" *) type_synonym combinatorial_auction_pred = "goods \ participant set \ bids \ allocation_rel \ payments \ bool" type_synonym combinatorial_auction_tup = "(goods \ participant set \ bids) \ (allocation_rel \ payments)" type_synonym combinatorial_auction_rel = "combinatorial_auction_tup set" section {* Valid input *} type_synonym input_validity = "goods \ participant set \ bids \ bool" text {* Valid input (i.e.\ valid bids w.r.t.\ the goods and participants). As we represent @{typ bids} as functions, which are always total in Isabelle/HOL, we can't simply test, e.g., whether their domain is @{term "G \ N"} for the given goods @{term G} and participants @{term N}. All we can enforce are non-empty finite sets of goods and participants, and that the bids are non-negative. *} (* CL: Once we realise general/special auctions using locales, we need a valid_input axiom. *) definition valid_input :: "goods \ participant set \ bids \ bool" where "valid_input G N b \ card G > 0 \ card N > 0 \ (\ n H . n \ N \ H \ G \ b n H \ 0)" section {* Allocations *} text {* the value (according to the bids submitted) of a certain allocation *} fun value_rel :: "bids \ allocation_rel \ price" where "value_rel b buyer = (\ y \ Domain buyer . b (buyer ,, y) y (* CL@CR: This implicitly assumes a value of 0 for goods not sold. OK? Goods not sold don't occur in the potential_buyer relation and therefore won't be summands of this sum. *) )" (* CL: probably not needed, neither for close-to-paper nor for computable version definition value_fun :: "bids \ allocation_fun \ price" where "value_fun b Yp = (let Y = fst Yp; buyer = snd Yp in \ y \ Y . (let n = buyer y in case n of None \ 0 (* CL@CR: OK to assume a value of 0 for goods not sold? *) | Some n \ b n y))" *) text {* all possible allocations of a set of goods to a set of participants: injective functions that map sets of goods to their potential buyers, i.e.\ participants *} fun possible_allocations_rel :: "goods \ participant set \ allocation_rel set" where "possible_allocations_rel G N = \ { injections Y N | Y . Y \ all_partitions G }" notepad begin fix Rs::"('a \ 'b) set set" fix Sss::"'a set set" fix P::"'a set \ ('a \ 'b) set set" (* TODO CL: an example (to be mentioned in the paper) for how hard set theory is for Isabelle: takes several minutes to find, 104 ms to prove *) have "{ R . \ Y \ Sss . R \ P Y } = \ { P Y | Y . Y \ Sss }" by (smt Collect_cong Union_eq mem_Collect_eq) end text {* algorithmic version of @{const possible_allocations_rel} *} fun possible_allocations_alg :: "goods \ participant set \ allocation_rel list" where "possible_allocations_alg G N = concat [ injections_alg Y N . Y \ all_partitions_alg G ]" (* example (uncomment to run): possibilities to allocate goods {1,2,3} to participants {100,200} *) (* value "possible_allocations_alg {1,2,3::nat} {100,200::nat}" *) (* CL: probably not needed, neither for close-to-paper nor for computable version definition possible_allocations_fun :: "goods \ participant set \ allocation_fun set" where "possible_allocations_fun G N = { (Y,potential_buyer) . Y \ all_partitions G \ (\ y \ Y . (\ n \ N . potential_buyer y = Some n) \ potential_buyer y = None) \ inj_on potential_buyer Y }" *) section {* Relational vs. predicate form*} text {* A general combinatorial auction in predicate form. To give the auction designer flexibility (including the possibility to introduce mistakes), we only constrain the left hand side of the relation, as to cover valid inputs. This definition makes sure that whenever we speak of a combinatorial auction, there is a valid input on the left hand side. In other words, this predicate returns false for relations having left hand side entries that are known not to be valid inputs. For this and other reasons (including Isabelle's difficulties to handle complex set comprehensions) it is more convenient to treat the auction as a predicate over all of its arguments, instead of a left-hand-side/right-hand-side relation.*} definition pred :: "goods \ participant set \ bids \ allocation_rel \ payments \ bool" where "pred G N b x p \ valid_input G N b" text {* Given an auction in predicate form @{const pred}, construct a predicate that takes all arguments of @{const pred} as one @{term "(input, outcome)"} pair, and checks whether its components satisfy @{const pred}. This is useful for modelling the auction in relational form. *} definition pred_tup :: "combinatorial_auction_pred \ combinatorial_auction_tup \ bool" where "pred_tup P T \ (\ G N b x p . T = ((G, N, b), (x, p)) \ P G N b x p)" text {* We construct the relational form of an auction from the predicate form @{const pred}: given a predicate that defines an auction by telling us for all possible arguments whether they form an @{term "(input, outcome)"} pair according to the auction's definition, we construct a predicate that tells us whether all @{term "(input, outcome)"} pairs in a given relation satisfy that predicate, i.e.\ whether the given relation is an auction of the desired type. *} definition rel_sat_pred :: "combinatorial_auction_pred \ combinatorial_auction_rel \ bool" where "rel_sat_pred P A \ (\ T \ A . pred_tup P T)" (* TODO CL: Now that we have rel_all, check whether this is still needed. rel_sat_pred could also now be defined as "A \ (rel_all P)" *) text {* A variant of @{const rel_sat_pred}: We construct a predicate that tells us whether the given relation comprises \emph{all} @{term "(input, outcome)"} pairs that satisfy the given auction predicate, i.e.\ whether the given relation comprises all possible auctions of the desired type. *} definition rel_all_pred :: "combinatorial_auction_pred \ combinatorial_auction_rel \ bool" where "rel_all_pred P A \ (\ T . T \ A \ pred_tup P T)" (* TODO CL: document *) definition rel_all :: "combinatorial_auction_pred \ combinatorial_auction_rel" where "rel_all P = { T . pred_tup P T }" (* TODO CL: document *) lemma pred_imp_rel_all: "P G N b x p \ ((G, N, b), (x, p)) \ rel_all P" unfolding rel_all_def using pred_tup_def mem_Collect_eq by force end