Courses/CS 460/Fall 2005/Homework/Cynthia York/Oct 29
From CSWiki
< Courses | CS 460 | Fall 2005 | Homework | Cynthia York
[edit] The Band
- Presented this in class
- The Band Puzzle creates a bandMate record with an element for each given name of the group. These elements have property/value pairs of instrument make, instrument type, magazine and surname. It then assigns values to each property based on the following clues:
- Steve wasn't the sound engineer. One of the women enjoyed EQ magazine.
- Angie and Steve didn't like Recording magazine. The bass player used Ibanez equipment.
- Mr. Magnus didn't use Mackie equipment. Mark's last name wasn't Hydal and he didn't play keyboard.
- The sound engineer, whose last name wasn't Engel, enjoyed reading Mix magazine. The person who used Yamaha drums wasn't Robert, but their last name is Hydal.
- The five band members (in no particular order) were: Mark Scott, the female bass player, the person who read Musician, the one who used Peavey equipment, and Robert.
- Shelley's last name was not Hydal or McArthur and she didn't use Roland equipment. Mackie only developed equipment for live sound and recording NOT musical instruments.
- Steve McArthur was the guitarist.
% TheBand % UTILITIES declare % Every member of Xs has a value from Values. % Instantiates those that don't. proc {AllInstantiated Xs Values} {ForAll Xs proc {$ X} {IsIn X Values} end} end proc {IsIn ?X Xs} {Append _ X|_ Xs} end proc {Append ?Xs ?Ys ?Zs} choice Xs = nil Ys = Zs [] X Xr in Xs = X | Xr Zs = X | {Append Xr Ys} end end % Creates a list of the values for Field in the elements % of Elts. Assumes Elts is a homgeneous list whose % members are records with a field named Field. fun {GetFields Field Elts} {Map Elts fun {$ Elt} Elt.Field end} end % Returns the first index of X in Xs. X and Xs must be % instantiated or will suspend until they are. % Fails if X is not in Xs. fun {IndexOf X Xs} fun {IndexOf3 X Xs N} case Xs of nil then fail [] Y | Rest then if X == Y then N else {IndexOf3 X Rest N+1} end end end in {IndexOf3 X Xs 1} end proc {IsAnElt ?X Elts} {IsIn X {Record.toList Elts}} end % CONTRAINTS % Generate thread bombs that ensure that all the members % of List are distinct. proc {AllDistinct List} L = {Length List} in for I in 1; I =< L-1; I+1 do for J in I+1; J =< L; J+1 do {NotEqual {Nth List I} {Nth List J}} end end end % Plant a thread bomb that goes off if X and Y become % instantiated to the same value. proc {NotEqual X Y} thread X == Y = false end end % A thread bomb that ensures that X1 precedes X2 in Xs. proc {Precedes ?X1 ?X2 Xs} thread {IndexOf X1 Xs} < {IndexOf X2 Xs} = true end end % PROPAGATOR UTILITIES % If the fields common to R1 and R2 are all instantiated, returns % true/false depending on whether they are all equal (==). % Suspends until fields become instantiated. fun {Match R1 R2} {Record.all {Record.zip R1 R2 fun {$ A B} A == B end} fun {$ X} X == true end} end % If {Match Condition R} then {UnifyRecs Result R}. % Does this in a thread to avoid blocking the main thread. % Also acts as a constraint in case the unification fails. proc {Propagate Condition Result R} thread if {Match Condition R} then {UnifyRecs Result R} end end end % Propagates Condition -> Result to all the fields in the record Rec. % Each field is done in its own thread. See Propagate. proc {PropagateAll Condition Result Rec} {Record.forAll Rec proc {$ R} {Propagate Condition Result R} end} end % Unifies the values of the fields common to R1 and R2 proc {UnifyRecs R1 R2} {Record.zip R1 R2 fun {$ A B} A = B end _} end % PROBLEM SPECIFIC local Surnames = ['Engel' 'Hydal' 'Magnus' 'McArthur' 'Scott'] InstMakes = ['Ibanez' 'Mackie' 'Peavey' 'Roland' 'Yamaha'] InstTypes = [bass drums guitar keyboard sound] Magazines = ['EQ' 'Home Recording' 'Mix' 'Musician' 'Recording'] % Had to add the following property types to negate a property % value when no specific record was known % Name is a surname proc {IsASurname ?Name} {IsIn Name Surnames} end % Make is an instrument make proc {IsAnInstMake ?Make} {IsIn Make InstMakes} end % Type is an instrument type proc {IsAnInstType ?Type} {IsIn Type InstTypes} end % Mag is a magazine proc {IsAMagazine ?Mag} {IsIn Mag Magazines} end proc {Clue1 Elts} % Steve wasn't the sound engineer {NotEqual Elts.'Steve'.instType sound} % One woman enjoyed EQ magazine choice Elts.'Angie'.magazine = 'EQ' [] Elts.'Shelley'.magazine = 'EQ' end end proc {Clue2 Elts} % Angie & Steve didn't like Recording magazine {NotEqual Elts.'Angie'.magazine 'Recording'} {NotEqual Elts.'Steve'.magazine 'Recording'} % the bass player used Ibanez equipment {PropagateAll properties(instMake:'Ibanez') properties(instType:bass) Elts} end proc {Clue3 Elts} Name in % Mr. Magnus didn't use Mackie equipment {PropagateAll properties(instMake:'Mackie') properties(surname:Name) Elts} {IsASurname Name} Name == 'Magnus' = false {NotEqual Elts.'Angie'.surname 'Magnus'} {NotEqual Elts.'Shelley'.surname 'Magnus'} % Mark's last name wasn't Hydal and he didn't play keyboard {NotEqual Elts.'Mark'.surname 'Hydal'} {NotEqual Elts.'Mark'.instType keyboard} end proc {Clue4 Elts} Surname in % The sound engineer, whose last name wasn't Engel, enjoyed % reading Mix magazine {PropagateAll properties(instType:sound) properties(magazine:'Mix') Elts} {PropagateAll properties(instType:sound) properties(surname:Surname) Elts} {IsASurname Surname} Surname == 'Engel' = false % The person who used Yamaha drums wasn't Robert, but their % last name is Hydal {PropagateAll properties(surname:'Hydal') properties(instMake:'Yamaha') Elts} {PropagateAll properties(surname:'Hydal') properties(instType:drums) Elts} {NotEqual Elts.'Robert'.surname 'Hydal'} end proc {Clue5 Elts} % The five band members (in no particular order) were: % Mark Scott, Elts.'Mark'.surname = 'Scott' {NotEqual Elts.'Mark'.instType bass} {NotEqual Elts.'Mark'.magazine 'Musician'} {NotEqual Elts.'Mark'.instMake 'Peavey'} %the female bass player, %the person who reads Musician, %the one who used Peavey equipment choice Elts.'Angie'.instType = bass [] Elts.'Angie'.magazine = 'Musician' [] Elts.'Angie'.instMake = 'Peavey' end choice Elts.'Shelley'.instType = bass [] Elts.'Shelley'.magazine = 'Musician' [] Elts.'Shelley'.instMake = 'Peavey' end choice Elts.'Steve'.magazine = 'Musician' [] Elts.'Steve'.instMake = 'Peavey' end % and Robert {NotEqual Elts.'Robert'.instType bass} {NotEqual Elts.'Robert'.magazine 'Musician'} {NotEqual Elts.'Robert'.instMake 'Peavey'} end proc {Clue6 Elts} % Shelley's last name was not Hydal or McArthur and she didn't % use Roland equipment. {NotEqual Elts.'Shelley'.surname 'Hydal'} {NotEqual Elts.'Shelley'.surname 'McArthur'} {NotEqual Elts.'Shelley'.instMake 'Roland'} % Mackie only developed equipment for live sound and recording % NOT musical instruments {PropagateAll properties(instType:sound) properties(instMake:'Mackie') Elts} end proc {Clue7 Elts} % Steve McArthur was the guitarist. Elts.'Steve'.surname = 'McArthur' Elts.'Steve'.instType = guitar end fun {TheBand} Elts = {MakeRecord bandMates ['Angie' 'Mark' 'Robert' 'Shelley' 'Steve']} Sn IM IT Mg BandMates = {Record.toList Elts} in % Create property records for each band member {Record.forAll Elts proc {$ M} M = {Record.make properties [surname instMake instType magazine]} end} % Get the lists of property variables. % Constrain them to be distinct. Sn = {GetFields surname BandMates} {AllDistinct Sn} IM = {GetFields instMake BandMates} {AllDistinct IM} IT = {GetFields instType BandMates} {AllDistinct IT} Mg = {GetFields magazine BandMates} {AllDistinct Mg} % Run the clues {Clue1 Elts} {Clue2 Elts} {Clue3 Elts} {Clue4 Elts} {Clue5 Elts} {Clue6 Elts} {Clue7 Elts} % Ensure that every property has a value. {AllInstantiated IM InstMakes} {AllInstantiated IT InstTypes} {AllInstantiated Mg Magazines} {AllInstantiated Sn Surnames} % Return Elts as the answer Elts end in {Browse {SearchAll TheBand}} end[edit] Zoo Feeding Time
- Zookeeper George was in charge of feeding all of the animals in the morning. He had a regular schedule that he followed every day. Can you figure it out from the clues?
- Feeding times are 6:30, 6:45, 7:00, 7:15 and 7:30.
- The giraffes were fed before the zebras but after the monkeys.
- The bears were fed 15 minutes after the monkeys.
- The lions were fed after the zebras.
%ZooFeedingTime % UTILITIES declare % Every member of Xs has a value from Values. % Instantiates those that don't. proc {AllInstantiated Xs Values} {ForAll Xs proc {$ X} {IsIn X Values} end} end proc {IsIn ?X Xs} {Append _ X|_ Xs} end proc {Append ?Xs ?Ys ?Zs} choice Xs = nil Ys = Zs [] X Xr in Xs = X | Xr Zs = X | {Append Xr Ys} end end % Creates a list of the values for Field in the elements % of Elts. Assumes Elts is a homgeneous list whose % members are records with a field named Field. fun {GetFields Field Elts} {Map Elts fun {$ Elt} Elt.Field end} end % Returns the first index of X in Xs. X and Xs must be % instantiated or will suspend until they are. % Fails if X is not in Xs. fun {IndexOf X Xs} fun {IndexOf3 X Xs N} case Xs of nil then fail [] Y | Rest then if X == Y then N else {IndexOf3 X Rest N+1} end end end in {IndexOf3 X Xs 1} end proc {IsAnElt ?X Elts} {IsIn X {Record.toList Elts}} end % CONTRAINTS % Generate thread bombs that ensure that all the members % of List are distinct. proc {AllDistinct List} L = {Length List} in for I in 1; I =< L-1; I+1 do for J in I+1; J =< L; J+1 do {NotEqual {Nth List I} {Nth List J}} end end end % Plant a thread bomb that goes off if X and Y become % instantiated to the same value. proc {NotEqual X Y} thread X == Y = false end end % A thread bomb that ensures that X1 precedes X2 in Xs. proc {Precedes ?X1 ?X2 Xs} thread {IndexOf X1 Xs} < {IndexOf X2 Xs} = true end end % Add two Follows procs % A thread bomb that ensures that X1 follows X2 in Xs. proc {Follows ?X1 ?X2 Xs} thread {IndexOf X1 Xs} > {IndexOf X2 Xs} = true end end % A thread bomb that ensures that X1 follows X2 in Xs. proc {ImmediatelyFollows ?X1 ?X2 Xs} thread {IndexOf X1 Xs} == {IndexOf X2 Xs} + 1 = true end end % PROPAGATOR UTILITIES % If the fields common to R1 and R2 are all instantiated, returns % true/false depending on whether they are all equal (==). % Suspends until fields become instantiated. fun {Match R1 R2} {Record.all {Record.zip R1 R2 fun {$ A B} A == B end} fun {$ X} X == true end} end % If {Match Condition R} then {UnifyRecs Result R}. % Does this in a thread to avoid blocking the main thread. % Also acts as a constraint in case the unification fails. proc {Propagate Condition Result R} thread if {Match Condition R} then {UnifyRecs Result R} end end end % Propagates Condition -> Result to all the fields in the record Rec. % Each field is done in its own thread. See Propagate. proc {PropagateAll Condition Result Rec} {Record.forAll Rec proc {$ R} {Propagate Condition Result R} end} end % Unifies the values of the fields common to R1 and R2 proc {UnifyRecs R1 R2} {Record.zip R1 R2 fun {$ A B} A = B end _} end % PROBLEM SPECIFIC local Times = ['6:30' '6:45' '7:00' '7:15' '7:30'] proc {Clue1 Elts} Time in %The giraffes were fed Elts.giraffes.time = Time %before the zebras {Precedes Time Elts.zebras.time Times} %but after the monkeys. {Follows Time Elts.monkeys.time Times} end proc {Clue2 Elts} Time in %The bears were fed Elts.bears.time = Time %15 minutes after the monkeys. {ImmediatelyFollows Time Elts.monkeys.time Times} end proc {Clue3 Elts} Time in %The lions were fed Elts.lions.time = Time %after the zebras. {Follows Time Elts.zebras.time Times} end fun {ZooFeedingTime} Elts = {MakeRecord animals [bears giraffs lions monkeys zebras] } {Browse 'ZooFeedingTime-Elts:'#Elts} Tm Animals = {Record.toList Elts} in % Create property records for each animal {Record.forAll Elts proc {$ A} A = {Record.make properties [time]} end} {Browse 'ZooFeedingTime-Elts:'#Elts} % Get the list of property variables. % Constrain them to be distinct. Tm = {GetFields times Animals} {AllDistinct Tm} {Browse 'ZooFeedingTime-Tm:'#Tm} % Run the clues {Clue1 Elts} %{Clue2 Elts} %{Clue3 Elts} % Ensure that every property has a value. {AllInstantiated Tm Animals} % Return Elts as the answer Elts end in {Browse {SearchAll ZooFeedingTime}} end

