/tutorial/backtracking/logigram/logigram.e

http://github.com/tybor/Liberty · Specman e · 400 lines · 268 code · 34 blank · 98 comment · 0 complexity · 5bad5758e6609d422afb43e78babce78 MD5 · raw file

  1. -- See the Copyright notice at the end of this file.
  2. --
  3. class LOGIGRAM
  4. create {ANY}
  5. make
  6. feature {}
  7. description: DESCRIPTION
  8. situation: SITUATION
  9. make
  10. do
  11. create situation
  12. create description.make
  13. make_description
  14. situation.make(description)
  15. situation.solve
  16. end
  17. make_description
  18. do
  19. describe_problem_classic
  20. --describe_problem_small
  21. --describe_problem_jojo
  22. --describe_problem_big
  23. end
  24. feature {}
  25. describe_problem_classic
  26. -- A classic problem.
  27. -- Knowing that:
  28. -- - the house of the english is red,
  29. -- - the spanish has a dog,
  30. -- - one drink coffee in the green house,
  31. -- - the ukrainian drinks tea,
  32. -- - the green house is just at right of the ivory house,
  33. -- - the man that smokes winstons have a snail,
  34. -- - the man that smokes kools have the yellow house,
  35. -- - one drinks milk in the house at the middle,
  36. -- - the norvegian lives in the house at left,
  37. -- - the one who smokes chesterfields is neibourgh of a fox,
  38. -- - the one who smokes kools is neibourgh of a horse,
  39. -- - the one who smokes luckystrike drinks orange juice,
  40. -- - the japanese smokes parliaments,
  41. -- - the norvegian is neibourgh of the blue house.
  42. -- Tell who got the zebra and who drinks water?
  43. local
  44. a, b: ITEM
  45. do
  46. group_ordered("house", {ARRAY[STRING] 1, << "left", "mid-left", "middle", "mid-right", "right" >> })
  47. group_atomic("nationality", {ARRAY[STRING] 1, << "english", "spanish", "ukrainian", "norvegian", "japanese" >> })
  48. group_atomic("animal", {ARRAY[STRING] 1, << "dog", "fox", "zebra", "horse", "snail" >> })
  49. group_atomic("drink", {ARRAY[STRING] 1, << "tea", "milk", "orange juice", "coffee", "water" >> })
  50. group_atomic("cigarette", {ARRAY[STRING] 1, << "kools", "winston", "chesterfields", "luckystrike", "parliaments" >> })
  51. group_atomic("color", {ARRAY[STRING] 1, << "green", "ivory", "yellow", "blue", "red" >> })
  52. -- the house of the english is red
  53. rule(yes(item("nationality", "english"), item("color", "red")))
  54. -- the spanish has a dog
  55. rule(yes(item("nationality", "spanish"), item("animal", "dog")))
  56. -- one drink coffee in the green house
  57. rule(yes(item("drink", "coffee"), item("color", "green")))
  58. -- the ukrainian drinks tea
  59. rule(yes(item("nationality", "ukrainian"), item("drink", "tea")))
  60. -- the green house is just at right of the ivory house
  61. a := some("house")
  62. b := some("house")
  63. rule(eq(sub(ref(a), ref(b)), num(1))) -- a at right of b
  64. rule(yes(a, item("color", "green")))
  65. rule(yes(b, item("color", "ivory")))
  66. -- the man that smokes winstons have a snail
  67. rule(yes(item("cigarette", "winston"), item("animal", "snail")))
  68. -- the man that smokes kools have the yellow house
  69. rule(yes(item("cigarette", "kools"), item("color", "yellow")))
  70. -- one drinks milk in the house at the middle
  71. rule(yes(item("house", "middle"), item("drink", "milk")))
  72. -- the norvegian lives in the house at left
  73. rule(yes(item("house", "left"), item("nationality", "norvegian")))
  74. -- the one who smokes chesterfields is neibourgh of a fox
  75. a := some("house")
  76. b := some("house")
  77. rule(eq(abs(sub(ref(b), ref(a))), num(1))) -- neibourghs
  78. rule(yes(a, item("cigarette", "chesterfields")))
  79. rule(yes(b, item("animal", "fox")))
  80. -- the one who smokes kools is neibourgh of a horse
  81. a := some("house")
  82. b := some("house")
  83. rule(eq(abs(sub(ref(b), ref(a))), num(1))) -- neibourghs
  84. rule(yes(a, item("cigarette", "kools")))
  85. rule(yes(b, item("animal", "horse")))
  86. -- the one who smokes luckystrike drinks orange juice
  87. rule(yes(item("cigarette", "luckystrike"), item("drink", "orange juice")))
  88. -- the japanese smokes parliaments
  89. rule(yes(item("cigarette", "parliaments"), item("nationality", "japanese")))
  90. -- the norvegian is neibourgh of the blue house
  91. a := some("house")
  92. b := some("house")
  93. rule(eq(abs(sub(ref(b), ref(a))), num(1))) -- neibourghs
  94. rule(yes(a, item("nationality", "norvegian")))
  95. rule(yes(b, item("color", "blue")))
  96. end
  97. describe_problem_small
  98. -- A small problem for beginning and debugging
  99. -- * The one that had no child was born in 1804 and is not Marie.
  100. -- * Julie didn't have exactly one child and had fewer children than Marie.
  101. -- * The one that has 2 children was not born in 1805 and is not Eve.
  102. local
  103. a, b: ITEM
  104. do
  105. group_atomic("forname", {ARRAY[STRING] 1, << "marie", "julie", "eve" >> })
  106. group_numeric("children", {ARRAY[STRING] 1, << "0", "1", "2" >> })
  107. group_numeric("birth", {ARRAY[STRING] 1, << "1804", "1805", "1806" >> })
  108. rule(no(item("forname", "marie"), item("children", "0")))
  109. rule(yes(item("birth", "1804"), item("children", "0")))
  110. rule(no(item("forname", "julie"), item("children", "1")))
  111. rule(no(item("forname", "eve"), item("children", "2")))
  112. rule(no(item("birth", "1805"), item("children", "2")))
  113. a := some("children")
  114. b := some("children")
  115. rule(yes(a, item("forname", "marie")))
  116. rule(yes(b, item("forname", "julie")))
  117. rule(inf(ref(b), ref(a)))
  118. end
  119. describe_problem_jojo
  120. -- A problem from jojo.
  121. --
  122. -- After coming back to China from France, Wang Fox, a student
  123. -- in occidental history, discover that almost all his documents
  124. -- are lost. From its study about 5 ladies of a little french
  125. -- city in the first middle of the 19th century, he only
  126. -- remembers that:
  127. -- * fornames are Marie, Julie, Eve, Lucie, Zora.
  128. -- * they had from 0 to 4 children (no one the same count)
  129. -- * they are born between 1804 and 1808 (inclusive, no one the same)
  130. -- * they died between 1844 and 1848 (inclusive, no one the same)
  131. -- * The one who died in 1847 was born after the one having
  132. -- 3 children and two years before Eve.
  133. -- * The one not having any children has lived less
  134. -- long than Eve and 2 years less than the one
  135. -- born in 1806.
  136. -- * Marie did not have 4 children, she has lived
  137. -- at least 41 years and had more children than
  138. -- the one born in 1804.
  139. -- * Lucie died before Zora and had fewer
  140. -- children than the one died in 1844.
  141. --
  142. -- The same in french.
  143. -- * Celle morte en 1847 est née apres celle ayant eu 3 enfants et
  144. -- deux ans avant Eve.
  145. -- * Celle n'ayant pas eu d'enfants a vecu moins longtemps que Eve
  146. -- et 2 ans de moins que celle née en 1806.
  147. -- * Marie n'a pas eu 4 enfants, elle a vecu au moins 41 ans
  148. -- et a eu plus d'enfant que celle née en 1804.
  149. -- * Lucie est morte avant Zora et a eu moins d'enfants que celle
  150. -- decedée en 1844.
  151. local
  152. a, b, c, d, e, f: ITEM
  153. do
  154. group_atomic("forname", {ARRAY[STRING] 1, << "marie", "julie", "eve", "lucie", "zora" >> })
  155. group_numeric("children", {ARRAY[STRING] 1, << "0", "1", "2", "3", "4" >> })
  156. group_numeric("birth", {ARRAY[STRING] 1, << "1804", "1805", "1806", "1807", "1808" >> })
  157. group_numeric("death", {ARRAY[STRING] 1, << "1844", "1845", "1846", "1847", "1848" >> })
  158. -- * The one died in 1847 was born after the one having
  159. -- 3 children and two years before Eve.
  160. a := some("birth")
  161. b := some("birth")
  162. c := some("birth")
  163. rule(yes(a, item("death", "1847")))
  164. rule(yes(b, item("children", "3")))
  165. rule(yes(c, item("forname", "eve")))
  166. rule(sup(ref(a), ref(b)))
  167. rule(eq(add(ref(a), num(2)), ref(c)))
  168. -- * The one not having children has lived less
  169. -- longer than Eve and 2 years less than the one
  170. -- born in 1806.
  171. a := some("birth")
  172. d := some("death")
  173. e := some("death")
  174. f := some("death")
  175. rule(yes(a, item("children", "0")))
  176. rule(yes(d, item("children", "0")))
  177. rule(yes(e, item("birth", "1806")))
  178. rule(yes(f, item("forname", "eve")))
  179. rule(inf(sub(ref(d), ref(a)), sub(ref(f), ref(c))))
  180. rule(eq(add(sub(ref(d), ref(a)), num(2)), sub(ref(e), num(1806))))
  181. -- * Marie did not have 4 children, she has lived
  182. -- at least 41 years and had more child than
  183. -- the one born in 1804.
  184. rule(no(item("forname", "marie"), item("children", "4")))
  185. a := some("birth")
  186. b := some("death")
  187. rule(yes(a, item("forname", "marie")))
  188. rule(yes(b, item("forname", "marie")))
  189. rule(inf(num(40), sub(ref(b), ref(a))))
  190. a := some("children")
  191. b := some("children")
  192. rule(yes(a, item("birth", "1804")))
  193. rule(yes(b, item("forname", "marie")))
  194. rule(inf(ref(a), ref(b)))
  195. -- * Lucie died before zora and had less
  196. -- children than the one died in 1844.
  197. a := some("death")
  198. b := some("death")
  199. rule(yes(a, item("forname", "lucie")))
  200. rule(yes(b, item("forname", "zora")))
  201. rule(inf(ref(a), ref(b)))
  202. a := some("children")
  203. b := some("children")
  204. rule(yes(a, item("forname", "lucie")))
  205. rule(yes(b, item("death", "1844")))
  206. rule(inf(ref(a), ref(b)))
  207. end
  208. describe_problem_big
  209. -- a big problem not translated
  210. local
  211. a, b: ITEM
  212. do
  213. group_atomic("film", {ARRAY[STRING] 1, << "10", "coup", "corse", "prix", "vipere" >> })
  214. group_atomic("acteur", {ARRAY[STRING] 1, << "emilio", "gerard", "louis", "norbert", "sammy" >> })
  215. group_atomic("animal", {ARRAY[STRING] 1, << "cheval", "cobra", "chien", "singe", "tigre" >> })
  216. group_ordered("jour", {ARRAY[STRING] 1, << "lundi", "mardi", "mercredi", "jeudi", "vendredi" >> })
  217. group_numeric("prise", {ARRAY[STRING] 1, << "2", "3", "4", "6", "8" >> })
  218. group_atomic("lieu", {ARRAY[STRING] 1, << "cuisine", "champ", "escalier", "foret", "rue" >> })
  219. group_numeric("scene", {ARRAY[STRING] 1, << "30", "60", "120", "180", "240" >> })
  220. group_atomic("ennui", {ARRAY[STRING] 1, << "agressivite", "fuite", "immobilite", "panique", "panne" >> })
  221. rule(no(item("ennui", "fuite"), item("animal", "cobra")))
  222. rule(no(item("ennui", "fuite"), item("acteur", "emilio")))
  223. rule(yes(item("acteur", "sammy"), item("film", "corse")))
  224. rule(no(item("acteur", "sammy"), item("jour", "jeudi")))
  225. rule(no(item("acteur", "sammy"), item("scene", "30")))
  226. rule(yes(item("lieu", "foret"), item("ennui", "panne")))
  227. a := some("jour")
  228. rule(yes(a, item("prise", "8")))
  229. b := some("jour")
  230. rule(yes(b, item("film", "vipere")))
  231. rule(eq(add(num(-2), ref(a)), ref(b)))
  232. b := some("jour")
  233. rule(yes(b, item("lieu", "foret")))
  234. rule(eq(add(num(1), ref(a)), ref(b)))
  235. rule(no(item("film", "vipere"), item("prise", "3")))
  236. rule(no(item("film", "vipere"), item("lieu", "rue")))
  237. rule(yes(item("lieu", "cuisine"), item("animal", "cobra")))
  238. rule(no(item("jour", "lundi"), item("animal", "cobra")))
  239. rule(no(item("jour", "mardi"), item("animal", "cobra")))
  240. rule(no(item("scene", "30"), item("animal", "cobra")))
  241. rule(no(item("scene", "60"), item("animal", "cobra")))
  242. rule(no(item("animal", "chien"), item("lieu", "escalier")))
  243. rule(no(item("animal", "chien"), item("ennui", "panique")))
  244. a := some("scene")
  245. rule(yes(a, item("film", "prix")))
  246. b := some("scene")
  247. rule(yes(b, item("animal", "cheval")))
  248. rule(eq(add(num(-60), ref(a)), ref(b)))
  249. b := some("scene")
  250. rule(yes(b, item("acteur", "norbert")))
  251. rule(eq(add(num(60), ref(a)), ref(b)))
  252. rule(no(item("jour", "lundi"), item("animal", "cheval")))
  253. rule(yes(item("acteur", "norbert"), item("prise", "6")))
  254. rule(no(item("acteur", "gerard"), item("jour", "lundi")))
  255. rule(no(item("acteur", "gerard"), item("scene", "120")))
  256. rule(no(item("film", "10"), item("acteur", "emilio")))
  257. rule(no(item("film", "10"), item("acteur", "norbert")))
  258. rule(no(item("film", "10"), item("prise", "2")))
  259. rule(no(item("film", "10"), item("prise", "3")))
  260. rule(no(item("animal", "tigre"), item("jour", "lundi")))
  261. rule(no(item("animal", "tigre"), item("jour", "mardi")))
  262. rule(no(item("animal", "tigre"), item("lieu", "rue")))
  263. rule(yes(item("animal", "tigre"), item("ennui", "immobilite")))
  264. rule(yes(item("scene", "180"), item("jour", "mardi")))
  265. rule(no(item("scene", "180"), item("prise", "6")))
  266. rule(no(item("scene", "180"), item("lieu", "escalier")))
  267. rule(no(item("scene", "180"), item("animal", "chien")))
  268. end
  269. feature {}
  270. group_atomic (nam: STRING; values: ARRAY[STRING])
  271. do
  272. description.add_group_atomic(nam)
  273. values.for_each(agent description.group.add_item(?))
  274. end
  275. group_numeric (nam: STRING; values: ARRAY[STRING])
  276. do
  277. description.add_group_numeric(nam)
  278. values.for_each(agent description.group.add_item(?))
  279. end
  280. group_ordered (nam: STRING; values: ARRAY[STRING])
  281. do
  282. description.add_group_ordered(nam)
  283. values.for_each(agent description.group.add_item(?))
  284. end
  285. feature {}
  286. rule (cstr: CONSTRAINT)
  287. do
  288. description.constraints.add(cstr)
  289. end
  290. no (i, j: ITEM): CONSTRAINT_NO
  291. do
  292. create Result.make(i, j)
  293. end
  294. yes (i, j: ITEM): CONSTRAINT_YES
  295. do
  296. create Result.make(i, j)
  297. end
  298. eq (i, j: EXPR): CONSTRAINT_EQUAL
  299. do
  300. create Result.make(i, j)
  301. end
  302. neq (i, j: EXPR): CONSTRAINT_NOT_EQUAL
  303. do
  304. create Result.make(i, j)
  305. end
  306. inf (i, j: EXPR): CONSTRAINT_LESSER
  307. do
  308. create Result.make(i, j)
  309. end
  310. sup (i, j: EXPR): CONSTRAINT_GREATER
  311. do
  312. create Result.make(i, j)
  313. end
  314. add (i, j: EXPR): EXPR_ADD
  315. do
  316. create Result.make(i, j)
  317. end
  318. sub (i, j: EXPR): EXPR_SUB
  319. do
  320. create Result.make(i, j)
  321. end
  322. mul (i, j: EXPR): EXPR_MUL
  323. do
  324. create Result.make(i, j)
  325. end
  326. abs (i: EXPR): EXPR_ABS
  327. do
  328. create Result.make(i)
  329. end
  330. num (i: INTEGER): EXPR_VALUE
  331. do
  332. create Result.make(i)
  333. end
  334. ref (i: ITEM): EXPR_ITEM
  335. do
  336. create Result.make(i)
  337. end
  338. item (group, name: STRING): ITEM_ITEM
  339. do
  340. Result := description.get_item(group, name)
  341. end
  342. var (group, name: STRING): ITEM_VAR
  343. do
  344. Result := description.get_var(group, name)
  345. end
  346. some (group: STRING): ITEM_VAR
  347. do
  348. Result := description.get_anonymous_var(group)
  349. end
  350. end -- class LOGIGRAM
  351. --
  352. -- ------------------------------------------------------------------------------------------------------------------------------
  353. -- Copyright notice below. Please read.
  354. --
  355. -- This file is free software, which comes along with SmartEiffel. This software is distributed in the hope that it will be
  356. -- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  357. -- You can modify it as you want, provided this footer is kept unaltered, and a notification of the changes is added.
  358. -- You are allowed to redistribute it and sell it, alone or as a part of another product.
  359. --
  360. -- Copyright(C) 1994-2002: INRIA - LORIA (INRIA Lorraine) - ESIAL U.H.P. - University of Nancy 1 - FRANCE
  361. -- Copyright(C) 2003-2005: INRIA - LORIA (INRIA Lorraine) - I.U.T. Charlemagne - University of Nancy 2 - FRANCE
  362. --
  363. -- Authors: Dominique COLNET, Philippe RIBET, Cyril ADRIAN, Vincent CROIZIER, Frederic MERIZEN
  364. --
  365. -- http://SmartEiffel.loria.fr - SmartEiffel@loria.fr
  366. -- ------------------------------------------------------------------------------------------------------------------------------