PageRenderTime 54ms CodeModel.GetById 44ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/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--
  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-- ------------------------------------------------------------------------------------------------------------------------------