(*
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