ZebraTutor

On this page, we illustrate by means of some simple puzzles how our tool (ZebraTutor) for explaining logic grid puzzles works. Each of the puzzles also contains a link to the actual ZebraTutor where you can interactively browse through the explanations. This page is still under construction. More puzzles will be added later.

Our Zebra is regularly given coffee by Jens Claes, Bart Bogaerts, Rocsildes Canoy, Emilio Gamba, Tias Guns, and the Japanese guy.


Origin puzzle

This puzzle, taken from the book "Puzzle Baron’s logic puzzles" concerns people's state of origin, current city of domicile, and age. The clues are:

  • Mattie is 113 years old,
  • The person who lives in Tehama is a native of either Kansas or Oregon",
  • The Washington native is 1 year older than Ernesto",
  • Roxanne is 2 years younger than the Kansas native",
  • The person who lives in Zearing isn't a native of Alaska",
  • The person who is 111 years old doesn't live in Plymouth",
  • The Oregon native is either Zachary or the person who lives in Tehama",
  • The person who lives in Shaver Lake is 1 year younger than Roxanne",
  • The centenarian who lives in Plymouth isn't a native of Alaska",
  • Of the person who lives in Tehama and Mattie, one is a native of Alaska and the other is from Kansas.

Input

The input of our system consists of these clues, combined with the following lexicon (the automated lexicon building does not yet work fully automatically):

	noun([year], [years]),
	noun([person], [persons]),
	noun([native], [natives]),
	noun([centenarian], [centenarians]),
	pn([mattie]),
	pn([tehama]),
	pn([kansas]),
	pn([oregon]),
	pn([washington]),
	pn([ernesto]),
	pn([roxanne]),
	pn([zearing]),
	pn([alaska]),
	pn([plymouth]),
	pn([zachary]),
	pn([shaver, lake]),
	tvPrep([lives], [in], [live], [lived]),
	copGap([], [old]),
	prep([of]),
	prep([from]),
	comp(higher, [older, than]),
	comp(lower, [younger, than])

IDP code

Our tool then generates the following translation of each of the clues in the IDP language (where ! is a universal quantifier, ? is an existential quantifier, & is conjunction, | is disjunction and ~ is negation )

	// Mattie is 113 years old
	is_old(mattie,113).

	// The person who lives in Tehama is a native of either Kansas or Oregon
	?a [native] b [native]: lives_in(a,tehama) & (of(b,kansas) | of(b,oregon)) & b = a.

	// The Washington native is 1 year older than Ernesto
	?c [native] d [year] e [year]: is_old(ernesto,d) & e = d+1 & is_old(c,e) & of(c,washington).

	// Roxanne is 2 years younger than the Kansas native
	?f [year] g [native] h [year]: is_old(g,f) & of(g,kansas) & h = f-2 & is_old(roxanne,h).

	// The person who lives in Zearing isn't a native of Alaska
	?i [native]: lives_in(i,zearing) & ~ (?j [native]: of(j,alaska) & j = i).

	// The person who is 111 years old doesn't live in Plymouth
	?k [native]: is_old(k,111) & ~ lives_in(k,plymouth).

	// The Oregon native is either Zachary or the person who lives in Tehama
	?l [native]: (zachary = l | (?m [native]: lives_in(m,tehama) & m = l)) & of(l,oregon).

	// The person who lives in Shaver Lake is 1 year younger than Roxanne
	?n [native] o [year] p [year]: lives_in(n,shaver_lake) & is_old(roxanne,o) & p = o-1 & is_old(n,p).

	// The centenarian who lives in Plymouth isn't a native of Alaska
	?q [native]: lives_in(q,plymouth) & ~ (?r [native]: of(r,alaska) & r = q).

	// Of the person who lives in Tehama and Mattie, one is a native of Alaska and the other is from Kansas
	?s [native]: lives_in(s,tehama) & ~ (s = mattie) & ((?t [native]: of(t,alaska) & t = s & from(mattie,kansas)) | (?u [native]: of(u,alaska) & u = mattie & from(s,kansas))).

The complete runnable IDP files for solving and explanation-generation can be obtained here.

These clues are combined with the implicit constraints underlying logic grid puzzles to solve the puzzle and finally to generate explanations. The interactive demonstrations of the explanations underlying this puzzle can be found following this link.


Tutorial puzzle

This puzzle is the tutorial taken from the website logicgridpuzzles.com. The puzzle is about people, their salary, the color of their house, and the medicin they take for their heart condition. The clues are given below. Strike-through and italic text means that we had to make some small replacements to help the parsing.

Input

The input of our system consists of these clues, combined with the following lexicon (the automated lexicon building does not yet work fully automatically):

	noun([patient], [patients]),
	noun([person], [people]),
	noun([year], [years]),
	noun([employee], [employees]),
	noun([salary], [salaries]),
	noun([owner], [owners]),
	pn([tatum]),
	pn([annabelle]),
	pn([heather]),
	pn([kassidy]),
	pn([benazepril]),
	pn([enalapril]),
	pn([ramipril]),
	pn([fosinopril]),
	prep([of]),
	ppn([the, blue, house]),
	ppn([the, lime, house]),
	ppn([the, cyan, house]),
	ppn([the, purple, house]),
	tv([owns], [own]),
	tvGap([earns], [per, year], [earn]),
	tvGap([was, prescribed], [for, their, heart, condition], [prescribe]),
	tvPrep([lives], [in], [live], [lived])

IDP code

Our tool then generates the following translation of each of the clues in the IDP language (where ! is a universal quantifier, ? is an existential quantifier, & is conjunction, | is disjunction and ~ is negation )

    // The 4 people were tatum, the patient who was prescribed enalapril, the employee who earns 54000, and the owner of the purple house
    ?a [owner] b [owner] c [owner]: ~ (tatum = a) & ~ (tatum = b) & ~ (tatum = c) & ~ (a = b) & ~ (a = c) & ~ (b = c) & was_prescribed_for_their_heart_condition(a,enalapril) & earns_per_year(b,54000) & of(c,the_purple_house).

    // The patient who was prescribed enalapril is not heather
    ?d [owner]: was_prescribed_for_their_heart_condition(d,enalapril) & ~ (heather = d).

    // The patient who was prescribed ramipril is not annabelle
    ?e [owner]: was_prescribed_for_their_heart_condition(e,ramipril) & ~ (annabelle = e).

    // kassidy earns less than heather
    ?f [type4] g [type2] h [type2]: f>0 & earns_per_year(heather,g) & h = g-f & earns_per_year(kassidy,h).

    // The owner of the blue house earns more than kassidy
    ?i [owner] j [type5] k [type2] l [type2]: of(i,the_blue_house) & j>0 & earns_per_year(kassidy,k) & l = k+j & earns_per_year(i,l).

    // Of tatum and annabelle, one earns 144000 per year and the other lives in the cyan house
    ~ (tatum = annabelle) & (earns_per_year(tatum,144000) & lives_in(annabelle,the_cyan_house) | earns_per_year(annabelle,144000) & lives_in(tatum,the_cyan_house)).

    // Either the employee who earns 144000  or the employee who earns 158000 lives in the blue house
    (?m [owner]: earns_per_year(m,144000) & lives_in(m,the_blue_house)) | (?n [owner]: earns_per_year(n,158000) & lives_in(n,the_blue_house)).

    // The owner of the lime house was prescribed enalapril for their heart condition
    ?o [owner]: of(o,the_lime_house) & was_prescribed_for_their_heart_condition(o,enalapril).

    // The employee who earns 144000 was prescribed benazepril for their heart condition
    ?p [owner]: earns_per_year(p,144000) & was_prescribed_for_their_heart_condition(p,benazepril).

The complete runnable IDP files for solving and explanation-generation can be obtained here.

These clues are combined with the implicit constraints underlying logic grid puzzles to solve the puzzle and finally to generate explanations. The interactive demonstrations of the explanations underlying this puzzle can be found following this link.