-
Notifications
You must be signed in to change notification settings - Fork 200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Find solution to Einstein's riddle with Apalache #113
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -35,12 +35,14 @@ | |||||||||||||||
|
||||||||||||||||
EXTENDS Naturals, FiniteSets | ||||||||||||||||
|
||||||||||||||||
House == 1..5 | ||||||||||||||||
|
||||||||||||||||
\* Note that TLC!Permutations has a Java module override and, thus, | ||||||||||||||||
\* would be evaluated faster. However, TLC!Permutations equals a | ||||||||||||||||
\* set of records whereas Permutation below equals a set of tuples/ | ||||||||||||||||
\* sequences. Also, Permutation expects Cardinality(S) = 5. | ||||||||||||||||
Permutation(S) == | ||||||||||||||||
{ p \in [ 1..5 -> S ] : | ||||||||||||||||
{ p \in [ House -> S ] : | ||||||||||||||||
/\ p[2] \in S \ {p[1]} | ||||||||||||||||
/\ p[3] \in S \ {p[1], p[2]} | ||||||||||||||||
/\ p[4] \in S \ {p[1], p[2], p[3]} | ||||||||||||||||
|
@@ -51,17 +53,22 @@ Permutation(S) == | |||||||||||||||
\* parameterization, the constants are replaced with constant-level | ||||||||||||||||
\* operators. As a side-effect, TLC evaluates them eagerly at startup, | ||||||||||||||||
\* and Apalache successfully determines their types. | ||||||||||||||||
NATIONALITIES == Permutation({ "brit", "swede", "dane", "norwegian", "german" }) | ||||||||||||||||
DRINKS == Permutation({ "beer", "coffee", "mylk", "tea", "water" }) | ||||||||||||||||
COLORS == Permutation({ "red", "white", "blue", "green", "yellow" }) | ||||||||||||||||
PETS == Permutation({ "bird", "cat", "dog", "fish", "horse" }) | ||||||||||||||||
CIGARS == Permutation({ "blend", "bm", "dh", "pm", "prince" }) | ||||||||||||||||
NATIONALITIES == Permutation({ "brit_OF_NATIONALITY", "swede_OF_NATIONALITY", "dane_OF_NATIONALITY", "norwegian_OF_NATIONALITY", "german_OF_NATIONALITY" }) | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Here is my suggestion on how to avoid specifying the type all the time. |
||||||||||||||||
DRINKS == Permutation({ "beer_OF_DRINK", "coffee_OF_DRINK", "mylk_OF_DRINK", "tea_OF_DRINK", "water_OF_DRINK" }) | ||||||||||||||||
COLORS == Permutation({ "red_OF_COLOR", "white_OF_COLOR", "blue_OF_COLOR", "green_OF_COLOR", "yellow_OF_COLOR" }) | ||||||||||||||||
PETS == Permutation({ "bird_OF_PET", "cat_OF_PET", "dog_OF_PET", "fish_OF_PET", "horse_OF_PET" }) | ||||||||||||||||
CIGARS == Permutation({ "blend_OF_CIGAR", "bm_OF_CIGAR", "dh_OF_CIGAR", "pm_OF_CIGAR", "prince_OF_CIGAR" }) | ||||||||||||||||
|
||||||||||||||||
VARIABLES | ||||||||||||||||
\* @type: Int -> NATIONALITY; | ||||||||||||||||
nationality, \* tuple of nationalities | ||||||||||||||||
\* @type: Int -> COLOR; | ||||||||||||||||
colors, \* tuple of house colors | ||||||||||||||||
\* @type: Int -> PET; | ||||||||||||||||
pets, \* tuple of pets | ||||||||||||||||
\* @type: Int -> CIGAR; | ||||||||||||||||
cigars, \* tuple of cigars | ||||||||||||||||
\* @type: Int -> DRINK; | ||||||||||||||||
drinks \* tuple of drinks | ||||||||||||||||
|
||||||||||||||||
------------------------------------------------------------ | ||||||||||||||||
|
@@ -70,44 +77,44 @@ VARIABLES | |||||||||||||||
(* Rules *) | ||||||||||||||||
(*********) | ||||||||||||||||
|
||||||||||||||||
BritLivesInTheRedHouse == \E i \in 2..5 : nationality[i] = "brit" /\ colors[i] = "red" | ||||||||||||||||
BritLivesInTheRedHouse == \E i \in 2..5 : nationality[i] = "brit_OF_NATIONALITY" /\ colors[i] = "red_OF_COLOR" | ||||||||||||||||
|
||||||||||||||||
SwedeKeepsDogs == \E i \in 2..5 : nationality[i] = "swede" /\ pets[i] = "dog" | ||||||||||||||||
SwedeKeepsDogs == \E i \in 2..5 : nationality[i] = "swede_OF_NATIONALITY" /\ pets[i] = "dog_OF_PET" | ||||||||||||||||
|
||||||||||||||||
DaneDrinksTea == \E i \in 2..5 : nationality[i] = "dane" /\ drinks[i] = "tea" | ||||||||||||||||
DaneDrinksTea == \E i \in 2..5 : nationality[i] = "dane_OF_NATIONALITY" /\ drinks[i] = "tea_OF_DRINK" | ||||||||||||||||
|
||||||||||||||||
GreenLeftOfWhite == \E i \in 1..4 : colors[i] = "green" /\ colors[i + 1] = "white" | ||||||||||||||||
GreenLeftOfWhite == \E i \in 1..4 : colors[i] = "green_OF_COLOR" /\ colors[i + 1] = "white_OF_COLOR" | ||||||||||||||||
|
||||||||||||||||
GreenOwnerDrinksCoffee == \E i \in 1..5 \ {3} : colors[i] = "green" /\ drinks[i] = "coffee" | ||||||||||||||||
GreenOwnerDrinksCoffee == \E i \in 1..5 \ {3} : colors[i] = "green_OF_COLOR" /\ drinks[i] = "coffee_OF_DRINK" | ||||||||||||||||
|
||||||||||||||||
SmokesPallmallRearsBirds == \E i \in 1..5 : cigars[i] = "pm" /\ pets[i] = "bird" | ||||||||||||||||
SmokesPallmallRearsBirds == \E i \in 1..5 : cigars[i] = "pm_OF_CIGAR" /\ pets[i] = "bird_OF_PET" | ||||||||||||||||
|
||||||||||||||||
YellowOwnerSmokesDunhill == \E i \in 1..5 : colors[i] = "yellow" /\ cigars[i] = "dh" | ||||||||||||||||
YellowOwnerSmokesDunhill == \E i \in 1..5 : colors[i] = "yellow_OF_COLOR" /\ cigars[i] = "dh_OF_CIGAR" | ||||||||||||||||
|
||||||||||||||||
CenterDrinksMylk == drinks[3] = "mylk" | ||||||||||||||||
CenterDrinksMylk == drinks[3] = "mylk_OF_DRINK" | ||||||||||||||||
|
||||||||||||||||
NorwegianFirstHouse == nationality[1] = "norwegian" | ||||||||||||||||
NorwegianFirstHouse == nationality[1] = "norwegian_OF_NATIONALITY" | ||||||||||||||||
|
||||||||||||||||
BlendSmokerLivesNextToCatOwner == | ||||||||||||||||
\E i \in 1..4 : | ||||||||||||||||
\/ cigars[i] = "blend" /\ pets[i + 1] = "cat" | ||||||||||||||||
\/ pets[i] = "cat" /\ cigars[i + 1] = "blend" | ||||||||||||||||
\/ cigars[i] = "blend_OF_CIGAR" /\ pets[i + 1] = "cat_OF_PET" | ||||||||||||||||
\/ pets[i] = "cat_OF_PET" /\ cigars[i + 1] = "blend_OF_CIGAR" | ||||||||||||||||
|
||||||||||||||||
HorseKeeperLivesNextToDunhillSmoker == | ||||||||||||||||
\E i \in 1..4 : | ||||||||||||||||
\/ cigars[i] = "dh" /\ pets[i + 1] = "horse" | ||||||||||||||||
\/ pets[i] = "horse" /\ cigars[i + 1] = "dh" | ||||||||||||||||
\/ cigars[i] = "dh_OF_CIGAR" /\ pets[i + 1] = "horse_OF_PET" | ||||||||||||||||
\/ pets[i] = "horse_OF_PET" /\ cigars[i + 1] = "dh_OF_CIGAR" | ||||||||||||||||
|
||||||||||||||||
BluemasterSmokerDrinksBeer == \E i \in 1..5 : cigars[i] = "bm" /\ drinks[i] = "beer" | ||||||||||||||||
BluemasterSmokerDrinksBeer == \E i \in 1..5 : cigars[i] = "bm_OF_CIGAR" /\ drinks[i] = "beer_OF_DRINK" | ||||||||||||||||
|
||||||||||||||||
GermanSmokesPrince == \E i \in 2..5 : nationality[i] = "german" /\ cigars[i] = "prince" | ||||||||||||||||
GermanSmokesPrince == \E i \in 2..5 : nationality[i] = "german_OF_NATIONALITY" /\ cigars[i] = "prince_OF_CIGAR" | ||||||||||||||||
|
||||||||||||||||
NorwegianLivesNextToBlueHouse == colors[2] = "blue" \* since the norwegian lives in the first house | ||||||||||||||||
NorwegianLivesNextToBlueHouse == colors[2] = "blue_OF_COLOR" \* since the norwegian_OF_NATIONALITY lives in the first house | ||||||||||||||||
|
||||||||||||||||
BlendSmokerHasWaterDrinkingNeighbor == | ||||||||||||||||
\E i \in 1..4 : | ||||||||||||||||
\/ cigars[i] = "blend" /\ drinks[i + 1] = "water" | ||||||||||||||||
\/ drinks[i] = "water" /\ cigars[i + 1] = "blend" | ||||||||||||||||
\/ cigars[i] = "blend_OF_CIGAR" /\ drinks[i + 1] = "water_OF_DRINK" | ||||||||||||||||
\/ drinks[i] = "water_OF_DRINK" /\ cigars[i + 1] = "blend_OF_CIGAR" | ||||||||||||||||
|
||||||||||||||||
------------------------------------------------------------ | ||||||||||||||||
|
||||||||||||||||
|
@@ -116,9 +123,9 @@ BlendSmokerHasWaterDrinkingNeighbor == | |||||||||||||||
(************) | ||||||||||||||||
|
||||||||||||||||
Init == | ||||||||||||||||
/\ drinks \in { p \in DRINKS : p[3] = "mylk" } | ||||||||||||||||
/\ nationality \in { p \in NATIONALITIES : p[1] = "norwegian" } | ||||||||||||||||
/\ colors \in { p \in COLORS : p[2] = "blue" } | ||||||||||||||||
/\ drinks \in { p \in DRINKS : p[3] = "mylk_OF_DRINK" } | ||||||||||||||||
/\ nationality \in { p \in NATIONALITIES : p[1] = "norwegian_OF_NATIONALITY" } | ||||||||||||||||
/\ colors \in { p \in COLORS : p[2] = "blue_OF_COLOR" } | ||||||||||||||||
/\ pets \in PETS | ||||||||||||||||
/\ cigars \in CIGARS | ||||||||||||||||
|
||||||||||||||||
|
@@ -146,4 +153,8 @@ Solution == | |||||||||||||||
|
||||||||||||||||
FindSolution == ~Solution | ||||||||||||||||
|
||||||||||||||||
\* To find the solution with the `^Apalache^' model-checker, run: | ||||||||||||||||
\* apalache-mc check --init=Init --inv=FindSolution --length=0 Einstein.tla | ||||||||||||||||
\* Then look for the file violation.tla in `^Apalache^' output directory. | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In case it is helpful, you can use the
|
||||||||||||||||
|
||||||||||||||||
============================================================ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just by looking at the set of constraints, I think you could define
Permutation
for the general case too:You could even replace$O(|S|^{|House|}*|House|^2)$
House
withS
, and it should still work in Apalache, as long asS
is a finite set. Of course, this definition would produce really a lot of constraints, something like