MrSlippery

Einstein's Engima solved by KLEE

Nov 22nd, 2015
424
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.85 KB | None | 0 0
  1. #include <klee/klee.h>
  2.  
  3. typedef enum {
  4.   NAT = 0,
  5.   COL = 1,
  6.   PET = 2,
  7.   DRI = 3,
  8.   SMO = 4
  9. } cols_type;
  10.  
  11. #define N 5
  12. char e[N*N];
  13.  
  14. int get_house(cols_type a, char a_value)
  15. {
  16.   int i;
  17.   for (i = 0; i < N; i++) {
  18.     if (a_value == e[i * N + a]) {
  19.       return i;
  20.     }
  21.   }
  22.   return -1;
  23. }
  24.  
  25. int connect_2(cols_type a, char a_value, cols_type b, char b_value)
  26. {
  27.   int house = get_house(a, a_value);
  28.   if (-1 == house) {
  29.     return 0;
  30.   }
  31.   return get_house(b, b_value) == house;
  32. }
  33.  
  34. int get_houses(cols_type a, char a_value, int *a_house, cols_type b, char b_value, int *b_house)
  35. {  
  36.   int a_h = get_house(a, a_value);
  37.   int b_h = get_house(b, b_value);
  38.   if (-1 == a_h || -1 == b_h) {
  39.     return 0;
  40.   }
  41.   *a_house = a_h;
  42.   *b_house = b_h;
  43.   return 1;
  44. }
  45.  
  46. int near(int a_house, int b_house) {
  47.   return (1 == (a_house - b_house)) ||
  48.          (-1 == (a_house - b_house));
  49. }
  50.  
  51. #define NEAR(ATTRIB_A, VALUE_A, ATTRIB_B, VALUE_B)\
  52. int VALUE_A ## _near_ ## VALUE_B() {\
  53.   int a_house, b_house;\
  54.   int houses = get_houses(ATTRIB_A, #VALUE_A[0], &a_house, ATTRIB_B, #VALUE_B[0], &b_house);\
  55.   if (!houses) {\
  56.     return 0;\
  57.   }\
  58.   return near(a_house, b_house);\
  59. }
  60.  
  61. int norwegian_first_house()
  62. {
  63.   return 'n' == e[0];
  64. }
  65.  
  66. int brit_house_red()
  67. {
  68.   return connect_2(NAT, 'b', COL, 'r');
  69. }
  70.  
  71. int swede_pet_dog()
  72. {
  73.   return connect_2(NAT, 's', PET, 'd');
  74. }
  75.  
  76. int dane_drink_tea()
  77. {
  78.   return connect_2(NAT, 'd', DRI, 't');
  79. }
  80.  
  81. NEAR(COL, g, COL, w)
  82.  
  83. int green_drink_coffee()
  84. {
  85.   return connect_2(COL, 'g', DRI, 'c');
  86. }
  87.  
  88. NEAR(SMO, n, PET, c)
  89.  
  90. int pall_pet_birds()
  91. {
  92.   return connect_2(SMO, 'p', PET, 'b');
  93. }
  94.  
  95. int yellow_smoke_dunhill()
  96. {
  97.   return connect_2(COL, 'y', SMO, 'd');
  98. }
  99.  
  100. int center_drink_milk()
  101. {
  102.   return 2 == get_house(DRI, 'm');
  103. }
  104.  
  105. int german_smoke_prince()
  106. {
  107.   return connect_2(NAT, 'g', SMO, 'r');
  108. }
  109.  
  110. NEAR(SMO, n, DRI, w)
  111. NEAR(NAT, n, COL, b)
  112. NEAR(PET, h, SMO, d)
  113.  
  114. int masters_drink_beer()
  115. {
  116.   return connect_2(SMO, 'm', DRI, 'b');
  117. }
  118.  
  119. int someone_pet_fish()
  120. {
  121.   return get_house(PET, 'f') >= 0;
  122. }
  123.  
  124. int main(int argc, char *argv[])
  125. {
  126.   klee_make_symbolic(e, sizeof(e), "e");
  127.   klee_assert(!(
  128.           /* The Norwegian lives in the first house. */
  129.                   norwegian_first_house() &&
  130.                   /* The Brit lives in the red house. */
  131.                   brit_house_red() &&
  132.                   /* The Swede keeps dogs as pets. */
  133.                   swede_pet_dog() &&
  134.                   /* The Dane drinks tea. */
  135.                   dane_drink_tea() &&
  136.                   /* The green house is just on the left of the white house. */
  137.                   g_near_w() &&
  138.                   /* The green house owner drinks coffee. */
  139.                   green_drink_coffee() &&
  140.                   /* The man who smokes Blend lives next to the one who keeps cats. */
  141.                   n_near_c() &&
  142.                   /* The person who smokes Pall Mall rears birds. */
  143.                   pall_pet_birds() &&
  144.                   /* The owner of the yellow house smokes Dunhill. */
  145.                   yellow_smoke_dunhill() &&
  146.                   /* The man living in the house right in the center drinks milk. */
  147.                   center_drink_milk() &&
  148.                   /* The German smokes Prince. */
  149.                   german_smoke_prince() &&
  150.                   /* The man who smokes Blend has a neighbor who drinks water. */
  151.                   n_near_w() &&
  152.                   /* The Norwegian lives next to the blue house. */
  153.                   n_near_b() &&
  154.                   /* The man who keeps horses lives next to the man who smokes Dunhill. */
  155.                   h_near_d() &&
  156.                   /* The owner who smokes Blue Master drinks beer. */
  157.                   masters_drink_beer() &&
  158.                   /* Someone has a fish */
  159.                   someone_pet_fish()
  160.            ));
  161.   return 0;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment