All Downloads are FREE. Search and download functionalities are using the official Maven repository.

models.examples.puzzles.handshake.als Maven / Gradle / Ivy

module examples/puzzles/handshake

/*
 * Alloy model of the Halmos handshake problem
 *
 * Hilary and Jocelyn are married. They invite four couples who are friends for dinner. When
 * they arrive, they shake hands with each other. Nobody shakes hands with him or herself
 * or with his or her spouse. After there has been some handshaking, Jocelyn jumps up on
 * a chair and says "Stop shaking hands!", and then asks how many hands each person has
 * shaken. All the answers are different. How many hands has Hilary shaken?
 *
 * The Alloy model represents the problem as a set of constraints. Properties of the spouse
 * relationship and of handshaking in general are given as facts. The particular situation
 * is cast as a function.
 *
 * There are 9 people answering, and all answers are different. Nobody can shake more than
 * 8 hands. So answers must be 0..8. The one (p8 say) who answered 8 has shaken everybody's
 * hand except for his or her own, and his or her spouse's. Now consider the person who shook
 * 0 hands (p0 say). The persons p0 and p8 are distinct. If they are not married, then p8 cannot
 * have shaken 8 hands, because he or she did not shake the hand of p0 or of his or her spouse.
 * So p8's spouse to p0. Now imagine Jocelyn asking the question again, with p0 and p8 out of
 * the room, and excluding hand shakes with them. Since p8 shook hands with everyone else
 * except p0 and p8, everyone gives an answer one smaller than they did before, giving 0..6.
 * The argument now applies recursively. So Hilary is left alone, having shaken 4 hands.
 *
 * author: Daniel Jackson, 11/15/01
 */

sig Person {spouse: Person, shaken: set Person}
one sig Jocelyn, Hilary extends Person {}

fact ShakingProtocol {
    // nobody shakes own or spouse's hand
    all p: Person | no (p + p.spouse) & p.shaken
    // if p shakes q, q shakes p
    all p, q: Person | p in q.shaken => q in p.shaken
    }

fact Spouses {
    all p, q: Person | p!=q => {
        // if q is p's spouse, p is q's spouse
        p.spouse = q => q.spouse = p
        // no spouse sharing
        p.spouse != q.spouse
        }
    all p: Person {
        // a person is his or her spouse's spouse
        p.spouse.spouse = p
        // nobody is his or her own spouse
        p != p.spouse
        }
    }

pred Puzzle {
    // everyone but Jocelyn has shaken a different number of hands
    all p,q: Person - Jocelyn | p!=q => #p.shaken != #q.shaken
    // Hilary's spouse is Jocelyn
    Hilary.spouse = Jocelyn
    }

P10: run Puzzle for exactly 10 Person, 5 int expect 1
P12: run Puzzle for exactly 12 Person, 5 int expect 1
P14: run Puzzle for exactly 14 Person, 5 int expect 1
P16: run Puzzle for exactly 16 Person, 6 int expect 1




© 2015 - 2025 Weber Informatics LLC | Privacy Policy