Home More Samples
```///////////////////////////////////////////////////////////////////////////////
//
// Title: Master Class
// Author: Constance D'Obigny
// Publication: Dell Logic Puzzles
// Issue: April, 1998
// Page: 12
// Stars: 2
//
// The great mezzo-soprano Flora Nebbiacorno has retired from the international
// opera stage, but she still teaches master classes regularly. At a recent
// class, her five students were one soprano, one mezzo-soprano, two tenors,
// and one bass. (The first two voice types are women's, and the last two are
// men's). Their first names are Chris, J.P., Lee, Pat, and Val -- any of which
// could  belong to a man or a woman -- and their last names are Kingsley,
// Robinson, Robinson (the two are unrelated but have the same last name),
// Ulrich, and Walker.
// Can you find the order in which these five sang for the class, identifying
// each by full name and voice type?
//
// 1. The first and second students were, in some order, Pat and the bass.
// 2. The second and third students included at least one tenor.
// 3. Kingsley and the fifth student (who isn't named Robinson) were, in some
//    order, a mezzo-soprano and a tenor.
// 4. Neither the third student, whose name is Robinson, nor Walker has the
//    first name of Chris.
// 5. Ulrich is not the bass or the mezzo-soprano.
// 6. Neither Lee or Val (who wasn't third) is a tenor.
// 7. J.P. wasn't third, and Chris wasn't fifth.
// 8. The bass isn't named Robinson.
//
// Determine: Order -- First name -- Last name -- Voice
///////////////////////////////////////////////////////////////////////////////
//
// Query:
//
//          all MasterClass(order,name,voice)
//
///////////////////////////////////////////////////////////////////////////////
//
// Result:
//
// order = [ {Chris} 4, {JP} 5, {Lee} 3, {Pat} 2, {Val} 1]
// name  = [ {Chris} Kingsley, {JP} Ulrich, {Lee} Robinson, {Pat} Robinson,
//           {Val} Walker]
// voice = [ {Chris} Mezzo_Soprano, {JP} Tenor, {Lee} Soprano, {Pat} Tenor,
//           {Val} Bass]
//
///////////////////////////////////////////////////////////////////////////////
//
// Notes:
//     In the code below, we declared two persons with Tenor voices
//     (voice1, voice2). These belong to two different persons, so we should
//     specify
//
//              voice1 <> voice2
//
//     However, this would lead to two identical solutions:
//
//     (1) JP = voice1, Pat = voice2
//     (2) JP = voice2, Pat = voice1
//
//     To avoid this, we simply insist that
//
//              voice1 > voice2
//
//     Basically, we ensure that only (1) or (2) will be generated, but never
//     both. This is a common scenario in many word puzzles.
//     (We also followed the same reasoning with robinson1, robinson2.)
//
///////////////////////////////////////////////////////////////////////////////

local FirstName = Chris | JP | Lee | Pat | Val
local LastName = Kingsley | Robinson | Ulrich | Walker
local Voice = Soprano | Mezzo_Soprano | Tenor | Bass

Voices = FirstName->Voice
Order = FirstName->>I[1..5]
Names = FirstName->LastName

pred MasterClass(order::Order,name::Names,voice::Voices) iff
voice(_) = Soprano &
voice(_) = Mezzo_Soprano &
voice(_) = Bass &
voice(voice1) = Tenor &
voice(voice2) = Tenor & voice1 > voice2 & {see the Notes above}

name(ulrich) = Ulrich &
name(kingsley) = Kingsley &
name(robinson1) = Robinson &
name(robinson2) = Robinson & robinson1 > robinson2 & {see the Notes above}
name(walker) = Walker &

// 1. The first and second students were, in some order, Pat and the bass.
order(first) = 1 & order(second) = 2 &
(
(first = Pat & voice(second) = Bass) |
(voice(first) = Bass & second = Pat)
) &

// 2. The second and third students included at least one tenor.
order(third) = 3 &
(voice(second) = Tenor | voice(third) = Tenor) &

// 3. Kingsley and the fifth student (who isn't named Robinson) were, in some
//    order, a mezzo-soprano and a tenor.
order(fifth) = 5 &
fifth <> robinson1 & fifth <> robinson2 &
(
(voice(kingsley) = Mezzo_Soprano & voice(fifth) = Tenor) |
(voice(kingsley) = Tenor & voice(fifth) = Mezzo_Soprano)
) &

// 4. Neither the third student, whose name is Robinson, nor Walker has the
//    first name of Chris.
(third = robinson1 | third = robinson2) &
third <> Chris & walker <> Chris &

// 5. Ulrich is not the bass or the mezzo-soprano.
voice(ulrich) <> Bass & voice(ulrich) <> Mezzo_Soprano &

// 6. Neither Lee or Val (who wasn't third) is a tenor.
voice(Lee) <> Tenor & voice(Val) <> Tenor & third <> Val &

// 7. J.P. wasn't third, and Chris wasn't fifth.
third <> JP & fifth <> Chris &

// 8. The bass isn't named Robinson.
voice(robinson1) <> Bass & voice(robinson2) <> Bass

```