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