Foundations of bilevel programming