| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| I never posted my solution to Whose Fish, and since my old thread probably has a stigma attached to it, I'll post it here. The object model contains two objects: House, and Street. Each of these objects inherit from EntityBase which is my Domain Supertype that adds validation rule handling and an IsValid property. Basically, my app creates and maintains 5 lists of houses based on house order. The program iterates through all permutations of house configurations (including house order), and only the valid houses are stored in the appropriate list (1st through 5th). Then I iterate through all permutations of valid houses to build a possible street and test its validity. This runs until a valid street is found. Rules are factored into two types of rules: house level, and street level. House level rules deal with one house configuration, and street rules deal the releationship of two houses to each other. It takes different amounts of time to run, depending on what order I put the enum / attributes in. Anywhere from 1 to 19 seconds tops. The first pass just filters houses using house rules, and contains only simple relative position rules (ones that can be determined soley from the "order" property). The resulting number of houses determines how many possible permutations of streets will need to be tested, so filtering is crucial at this level. A few more houses can result in thousands or millions of new streets to test. One breakthrough I had here was to extrapolate from the existing rules as many new rules as possible for the first round. This is how I got my max run time from literally days to 19 seconds tops! But like I said, i've seen it run in as little as a few seconds, depending on the inital order of attributes. All extrapolated rules are followed by a lowercase letter ("Rule4a", "Rule4b", etc). // - - - - - - the app - - - - - namespace Whose_Fish { class Program { static void Main(string[] args) { Program program = new Program(); program.CreateValidHouses(); program.CreateValidStreet(); } public Program() { InitHousesArray(); } // A list of lists that holds valid houses List<List<House>> Houses = new List<List<House>>(); void InitHousesArray() { Houses.Add(new List<House>()); // 1st house possibilities Houses.Add(new List<House>()); // 2nd house possibilities Houses.Add(new List<House>()); // 3rd house possibilities Houses.Add(new List<House>()); // 4th house possibilities Houses.Add(new List<House>()); // 5th house possibilities } void CreateValidHouses() { int[] slots = { 5, 5, 5, 5, 5, 5 }; PermutationGenerator gen = new PermutationGenerator(slots); foreach (List<int> p in gen) { // Create a possible house configuration House h = new House(); h.Nationality = (Nationalities)p[0]; h.HouseColor = (HouseColors)p[1]; h.Pet = (Pets)p[2]; h.Smoke = (Smokes)p[3]; h.Drink = (Drinks)p[4]; h.Order = p[5]; if (h.IsValid) { // Store valid houses by order Houses[h.Order].Add(h); } } } void CreateValidStreet() { Console.WindowHeight = 50; int[] slots = { Houses[0].Count, Houses[1].Count, Houses[2].Count, Houses[3].Count, Houses[4].Count }; PermutationGenerator gen = new PermutationGenerator(slots); Street street = new Street(); int count = 0; foreach (List<int> p in gen) { count += 1; // Create a possible street configuration street.Add(Houses[0][p[0]]); // Pick a house from list 1 street.Add(Houses[1][p[1]]); // Pick a house from list 2 street.Add(Houses[2][p[2]]); // Pick a house from list 3 street.Add(Houses[3][p[3]]); // Pick a house from list 4 street.Add(Houses[4][p[4]]); // Pick a house from list 5 // Test rules if (street.IsValid) { Console.Clear(); Console.WriteLine(street.DescribeStreet()); Console.WriteLine(); Console.WriteLine(string.Concat(count.ToString(), " of ", gen.Possibilities, " possibilities tested.")); break; } else { street.Clear(); } Console.WriteLine(count.ToString()); } // Wait for keystroke Console.WriteLine("\n[Press any key to exit]"); Console.ReadKey(); } } } // - - - - - - Object Model - - - - - namespace Entities { public enum Nationalities { Norwegian, Dane, German, Brit, Swede } public enum Pets { Horses, Fish, Cats, Birds, Dogs } public enum Drinks { Water, Milk, Coffee, Tea, Beer } public enum Smokes { Dunhills, Bluemasters, PallMalls, Princes, Blends } public enum HouseColors { Yellow, Blue, Green, Red, White } } namespace Entities { public class House : BusinessFramework.EntityBase { private Nationalities m_Nationality; private HouseColors m_Color; private Pets m_Pet; private Drinks m_Drink; private Smokes m_Smoke; private int m_Order; public Nationalities Nationality { get { return m_Nationality; } set { m_Nationality = value; } } public Pets Pet { get { return m_Pet; } set { m_Pet = value; } } public Drinks Drink { get { return m_Drink; } set { m_Drink = value; } } public Smokes Smoke { get { return m_Smoke; } set { m_Smoke = value; } } public HouseColors HouseColor { get { return m_Color; } set { m_Color = value; } } public int Order { get { return m_Order; } set { m_Order = value; } } public string Describe() { StringBuilder sb = new StringBuilder(); sb.Append("Nationality: \t").Append(this.Nationality.ToString()).Append("\ n"); sb.Append("Smokes:\t \t").Append(this.Smoke.ToString()).Append("\n"); sb.Append("Drinks:\t \t").Append(this.Drink.ToString()).Append("\n"); sb.Append("Pet:\t \t").Append(this.Pet.ToString()).Append("\n"); sb.Append("Color:\t \t").Append(this.HouseColor.ToString()).Append("\n \n"); return sb.ToString(); } #region Rules // House rules protected override void CheckRules() { AddRule("Rule1", "The Brit lives in the red house.", TestRule1()); AddRule("Rule2", "The Swede keeps dogs as pets.", TestRule2()); AddRule("Rule3", "The Dane drinks tea.", TestRule3()); AddRule("Rule5", "The green house owner drinks coffee.", TestRule5()); AddRule("Rule6", "The person who smokes Pall Malls keeps birds.", TestRule6()); AddRule("Rule7", "The owner of the yellow house smokes Dunhills.", TestRule7()); AddRule("Rule12", "The owner who smokes Bluemasters drinks beer.", TestRule12()); AddRule("Rule13", "The German smokes Princes.", TestRule13()); // Positional AddRule("Rule4a", "The green house cannot be 5th. (extrapolated from rule 4)", TestRule4a()); AddRule("Rule4b", "The green house is the 4th house. (extrapolated from rule 4)", TestRule4b()); AddRule("Rule4c", "The white house is the 4th or 5th house. (extrapolated from rule 4)", TestRule4c()); AddRule("Rule8", "Center house drinks milk.", TestRule8()); AddRule("Rule10", "The Norwegian lives in the 1st house.", TestRule10()); AddRule("Rule10_14a", "The blue house is 2nd. (extrapolated from rules 10 & 14)", TestRule10_14a()); } private bool TestRule1() { return !(this.HouseColor == HouseColors.Red && this.Nationality != Nationalities.Brit || this.Nationality == Nationalities.Brit && this.HouseColor != HouseColors.Red); } private bool TestRule2() { return !(this.Nationality == Nationalities.Swede && this.Pet != Pets.Dogs) || (Pet == Pets.Dogs && this.Nationality != Nationalities.Swede); } private bool TestRule3() { return !(this.Nationality == Nationalities.Dane && this.Drink != Drinks.Tea || this.Drink == Drinks.Tea && this.Nationality != Nationalities.Dane); } private bool TestRule6() { return !(this.Smoke == Smokes.PallMalls && this.Pet != Pets.Birds || this.Pet == Pets.Birds && this.Smoke != Smokes.PallMalls); } private bool TestRule7() { return !(this.HouseColor == HouseColors.Yellow && this.Smoke != Smokes.Dunhills || this.Smoke == Smokes.Dunhills && this.HouseColor != HouseColors.Yellow); } private bool TestRule12() { return !(this.Smoke == Smokes.Bluemasters && this.Drink != Drinks.Beer || this.Drink == Drinks.Beer && this.Smoke != Smokes.Bluemasters); } private bool TestRule13() { return !(this.Nationality == Nationalities.German && this.Smoke != Smokes.Princes || this.Smoke == Smokes.Princes && this.Nationality != Nationalities.German); } private bool TestRule5() { return !(this.HouseColor == HouseColors.Green && this.Drink != Drinks.Coffee || this.Drink == Drinks.Coffee && this.HouseColor != HouseColors.Green); } private bool TestRule4a() { return !(this.HouseColor == HouseColors.Green && this.Order == 4); } private bool TestRule8() { return !(this.Order == 2 && this.Drink != Drinks.Milk || this.Drink == Drinks.Milk && this.Order != 2); } private bool TestRule10() { return !(this.Nationality == Nationalities.Norwegian && this.Order != 0 || this.Order == 0 && this.Nationality != Nationalities.Norwegian); } private bool TestRule10_14a() { return !(this.HouseColor == HouseColors.Blue && this.Order != 1 || this.Order == 1 && this.HouseColor != HouseColors.Blue); } private bool TestRule4b() { return !(this.HouseColor == HouseColors.Green && (this.Order == 0 || this.Order == 1 || this.Order == 2 || this.Order == 4)); } private bool TestRule4c() { return !(this.HouseColor == HouseColors.White && (this.Order == 0 || this.Order == 1 || this.Order == 2)); } #endregion } } namespace Entities { /// <summary> /// A street is a collection of houses. /// </summary> public class Street : BusinessFramework.EntityBase { private List<House> m_Houses = new List<House>(); private House m_GreenHouse, m_WhiteHouse, m_BlendsHouse, m_DunhillsHouse, m_WaterHouse, m_HorseHouse, m_CatsHouse; public void Add(House house) { // Add to inner collection of houses m_Houses.Add(house); // Create shortcuts references for use in validation tests if (house.HouseColor == HouseColors.Green) m_GreenHouse = house; else if (house.HouseColor == HouseColors.White) m_WhiteHouse = house; if (house.Smoke == Smokes.Blends) m_BlendsHouse = house; else if (house.Smoke == Smokes.Dunhills) m_DunhillsHouse = house; if (house.Pet == Pets.Horses) m_HorseHouse = house; else if (house.Pet == Pets.Cats) m_CatsHouse = house; if (house.Drink == Drinks.Water) m_WaterHouse = house; } public House this[int index] { get { return m_Houses[index]; } set { m_Houses[index] = value; } } public void Clear() { // Clear inner list of houses m_Houses.Clear(); // Clear shortcut references m_GreenHouse = null; m_WhiteHouse = null; m_BlendsHouse = null; m_DunhillsHouse = null; m_HorseHouse = null; m_CatsHouse = null; m_WaterHouse = null; } public string DescribeStreet() { StringBuilder sb = new StringBuilder(); foreach (House h in m_Houses) { sb.Append(h.Describe()).Append("\n"); } return sb.ToString(); } #region Rules // Street rules protected override void CheckRules() { bool isUnique = TestRuleUnique(); AddRule("RuleUnique", "Houses must be unique.", isUnique); if (!isUnique) return; // Early exit clause AddRule("Rule4", "The green house is on the left of the white house.", TestRule4()); AddRule("Rule9", "The man who smokes Blends lives next to the one who keeps cats.", TestRule9()); AddRule("Rule11", "The man who keeps horses lives next to the one who smokes Dunhills.", TestRule11()); AddRule("Rule15", "The man who smokes Blends has a neighbor who drinks water.", TestRule15()); } private bool TestRuleUnique() { /* All checksums should add up to 10. * While it is possible to = 10 and still have non- * unique attributes, we know that if one doesn't = 10, * it cannot be valid, and therefore can be sacked without * further testing. */ int[] checkSums = new int[5]; // Add up checksums for street foreach (House h in m_Houses) { checkSums[0] += (int)h.HouseColor; checkSums[1] += (int)h.Drink; checkSums[2] += (int)h.Smoke; checkSums[3] += (int)h.Nationality; checkSums[4] += (int)h.Pet; } return (checkSums[0] == 10 && checkSums[1] == 10 && checkSums[2] == 10 && checkSums[3] == 10 && checkSums[4] == 10); } private bool TestRule4() { if (m_GreenHouse == null || m_WhiteHouse == null) return false; return !(m_GreenHouse.Order != m_WhiteHouse.Order - 1); } private bool TestRule9() { if (m_BlendsHouse == null || m_CatsHouse == null) return false; int difference = m_BlendsHouse.Order - m_CatsHouse.Order; return !(Math.Abs(difference) != 1); } private bool TestRule11() { if (m_DunhillsHouse == null || m_HorseHouse == null) return false; int difference = m_HorseHouse.Order - m_DunhillsHouse.Order; return !(Math.Abs(difference) != 1); } private bool TestRule15() { if (m_BlendsHouse == null || m_WaterHouse == null) return false; int difference = m_BlendsHouse.Order - m_WaterHouse.Order; return !(Math.Abs(difference) != 1); } #endregion } } Jordan |
|
#2
| |||
| |||
| Jordan Marr wrote: > I never posted my solution to Whose Fish, and since my old thread > probably has a stigma attached to it, I'll post it here. Come on, a mad catfight is not a "stigma" :-) > > The object model contains two objects: House, and Street. Each of > these objects inherit from EntityBase which is my Domain Supertype > that adds validation rule handling and an IsValid property. > Basically, my app creates and maintains 5 lists of houses based on > house order. The program iterates through all permutations of house > configurations (including house order), and only the valid houses are > stored in the appropriate list (1st through 5th). > > Then I iterate through all permutations of valid houses to build a > possible street and test its validity. This runs until a valid street > is found. > > Rules are factored into two types of rules: house level, and street > level. House level rules deal with one house configuration, and > street rules deal the releationship of two houses to each other. > > It takes different amounts of time to run, depending on what order I > put the enum / attributes in. Anywhere from 1 to 19 seconds tops. > > The first pass just filters houses using house rules, and contains > only simple relative position rules (ones that can be determined soley > from the "order" property). The resulting number of houses determines > how many possible permutations of streets will need to be tested, so > filtering is crucial at this level. A few more houses can result in > thousands or millions of new streets to test. One breakthrough I had > here was to extrapolate from the existing rules as many new rules as > possible for the first round. This is how I got my max run time from > literally days to 19 seconds tops! But like I said, i've seen it run > in as little as a few seconds, depending on the inital order of > attributes. All extrapolated rules are followed by a lowercase letter > ("Rule4a", "Rule4b", etc). > > // - - - - - - the app - - - - - [snip] I was thinking of a way to make this problem more real-world instead of textbook-puzzle-ish. One possible application would be crime solving, or perhaps terrorist tracking. Data about people, places, things, and relationships would all be in a data wearhouse and an inference engine of some type could chew on it to find potential trouble spots or leads. (Instead of "who has the fish", the questions may resemble, "who may have a bomb".) One change from your kind of solution is that specific instances would not be hard-wired into the app code. Classification systems would also not be hard-wired if we really don't want to make programmers glorified data entry clerks. People, places, things, and categories will be entered by domain experts, not programmers for the most part. It always seemed to me that if you remove domain classification from app code, the result will not be very OOP. There would be little or no need for inheritence or polymorphism. If you disagree, I would like to understand why, with perhaps some examples. -T- |
|
#3
| |||
| |||
| topmind wrote: > Jordan Marr wrote: >> I never posted my solution to Whose Fish, and since my old thread >> probably has a stigma attached to it, I'll post it here. > ** SNIP Jordan's original post ** > > I was thinking of a way to make this problem more real-world instead > of textbook-puzzle-ish. One possible application would be crime > solving, or perhaps terrorist tracking. Data about people, places, > things, and relationships would all be in a data wearhouse and an > inference engine of some type could chew on it to find potential > trouble spots or leads. (Instead of "who has the fish", the > questions may resemble, "who may have a bomb".) > So, changing the nouns makes the problem more 'real world'? I don't buy that. The problem was fine as it was IMO, and changing the nouns around wouldn't really add anything. However, an inference engine would certainly be an interesting way of solving the problem, I think. > One change from your kind of solution is that specific instances would > not be hard-wired into the app code. Classification systems would also > not be hard-wired if we really don't want to make programmers > glorified data entry clerks. People, places, things, and categories > will be entered by domain experts, not programmers for the most part. IMO, moving the noun definition outside of the hard-coded approach in the example neither adds nor takes away from the solution itself. The Sql approach that someone posted in the previous thread [1] was similar to Jordan's approach in this way, in that both of them were 'hard-wired' into the solution, as you say. The most interesting piece of this problem IMO is not how the houses, people, and streets get entered, but how the program goes about finding the correct answer given sets of these things and a set of rules. > It always seemed to me that if you remove domain classification from > app code, the result will not be very OOP. There would be little or no > need for inheritence or polymorphism. If you disagree, I would like to > understand why, with perhaps some examples. > Heck, Jordan's solution has very little inheritance or polymorphism. That doesn't mean I don't think it's a perfectly valid approach. > -T- > [1] http://groups.google.com/group/comp....c9e241f760a89a |
|
#4
| |||
| |||
| topmind wrote: > Jordan Marr wrote: >>I never posted my solution to Whose Fish, and since my old thread >>probably has a stigma attached to it, I'll post it here. > [snip] > I was thinking of a way to make this problem more real-world instead > of textbook-puzzle-ish. One possible application would be crime > solving, or perhaps terrorist tracking. You were told by me, last month, that the problem had real world application in anti-terrorist intelligence (posted on May 10th) . Can you guess what your reply (posted on May 22nd) was to this fact ... ?? > (Instead of "who has the fish", the questions may resemble, "who may have a bomb".) Feel free to change the example (and all the facts) to something else. I would suggest going to the site from where the "Whose fish" example came. IIRC the site had a collection of similar problems. One of those may save you the effort of having to construct a "real world" example. > One change from your kind of solution is that specific instances would > not be hard-wired into the app code. Classification systems would also > not be hard-wired if we really don't want to make programmers > glorified data entry clerks. People, places, things, and categories > will be entered by domain experts, not programmers for the most part. Fair enough. What does the SQL solution that was posted now look like without "hard-wired" schema information ?? > It always seemed to me that if you remove domain classification from > app code, the result will not be very OOP. There would be little or no > need for inheritence or polymorphism. If you disagree, I would like to > understand why, with perhaps some examples. An OO impl of a FOPL engine, vs a "P/R" one. It will be interesting to see your implementation of such an engine. Regards, Steven Perryman |
|
#5
| |||
| |||
| Kreeg wrote: > topmind wrote: > > Jordan Marr wrote: > >> I never posted my solution to Whose Fish, and since my old thread > >> probably has a stigma attached to it, I'll post it here. > > > ** SNIP Jordan's original post ** > > > > I was thinking of a way to make this problem more real-world instead > > of textbook-puzzle-ish. One possible application would be crime > > solving, or perhaps terrorist tracking. Data about people, places, > > things, and relationships would all be in a data wearhouse and an > > inference engine of some type could chew on it to find potential > > trouble spots or leads. (Instead of "who has the fish", the > > questions may resemble, "who may have a bomb".) > > > > So, changing the nouns makes the problem more 'real world'? I don't buy > that. The problem was fine as it was IMO, and changing the nouns > around wouldn't really add anything. You got me thinking. If you are doing a one-time or very specific simulation, then perhaps you are right. That is pretty much what Simula-67 was for, where OO was formally invented. They had tugboats, freighters, and loading docks and wanted to test the productivity of various scenarios. Simulations are certainly needed, otherwise Simula-67 wouldn't have been made. Perhaps the type of problems Simula was used for would be a better representation of a "real-world" version of this kind of puzzle than my crime/terrorist finder scenario. Being that I don't work on those kind of problems, I didn't really think about Simula-bound-stuff until now. However, my understanding is that simulation tools are becoming graphical in nature such that one drag and drops widgets and puts verious constraints on the visual "objects". There is coding, but it is mostly for event-handlers (if-bumped, if-moved, if-within-X-units- of-thing, etc.), not the framework itself. But I'll let a simulation expert make an informed comment on that. > > However, an inference engine would certainly be an interesting way of > solving the problem, I think. Perhaps that would just be reinventing Prolog :-) > > > One change from your kind of solution is that specific instances would > > not be hard-wired into the app code. Classification systems would also > > not be hard-wired if we really don't want to make programmers > > glorified data entry clerks. People, places, things, and categories > > will be entered by domain experts, not programmers for the most part. > > IMO, moving the noun definition outside of the hard-coded approach in > the example neither adds nor takes away from the solution itself. The > Sql approach that someone posted in the previous thread [1] was similar > to Jordan's approach in this way, in that both of them were 'hard-wired' > into the solution, as you say. > > The most interesting piece of this problem IMO is not how the houses, > people, and streets get entered, but how the program goes about finding > the correct answer given sets of these things and a set of rules. Again, It would be interesting to see a Prolog solution in the sense you tell it the logic rules and then ask questions over those rules. > > > It always seemed to me that if you remove domain classification from > > app code, the result will not be very OOP. There would be little or no > > need for inheritence or polymorphism. If you disagree, I would like to > > understand why, with perhaps some examples. > > > > Heck, Jordan's solution has very little inheritance or polymorphism. > That doesn't mean I don't think it's a perfectly valid approach. My comment was about the matter of being OO versus not being OO, not necessarily "valid" or not. Jordan's solution is not that OO. It mostly only uses encapsulation, not the other two. That is, the operations and data structures are bound together in the OO "self- handling-noun" way. Thus, on a continious scale, it has a fairly low amount of "OO-ness" if you will. A "direct" procedural solution would not be much different except that the data structures would be "naked". (Whether this is good or not will take us back to the ol' database versus app-RAM fights.) > > [1] http://groups.google.com/group/comp....c9e241f760a89a -T- |
|
#6
| |||
| |||
| S Perryman wrote: > topmind wrote: > > > Jordan Marr wrote: > > >>I never posted my solution to Whose Fish, and since my old thread > >>probably has a stigma attached to it, I'll post it here. > > > [snip] > > > I was thinking of a way to make this problem more real-world instead > > of textbook-puzzle-ish. One possible application would be crime > > solving, or perhaps terrorist tracking. > > You were told by me, last month, that the problem had real world > application in anti-terrorist intelligence (posted on May 10th) . I don't recall that, but if that was the case, then why not *present* an anti-terrorism problem, and give some sample scenarios? That way we don't *have to* deal with a text-book-puzzle-like problem. Cut out the middle-man. > > Can you guess what your reply (posted on May 22nd) was to this fact ... ?? > Nope. Let's hope it won't embarass me, however :-) > > > (Instead of "who has the fish", the questions may resemble, "who may have a bomb".) > > Feel free to change the example (and all the facts) to something else. Okay, how about a payroll example! > > I would suggest going to the site from where the "Whose fish" example came. > IIRC the site had a collection of similar problems. One of those may save > you the effort of having to construct a "real world" example. It is not my job to cull problems to present to comp.object. I already did a few and posted the source code on the web. Nobody has shown it objectively worse than Martin's version(s). > > > > One change from your kind of solution is that specific instances would > > not be hard-wired into the app code. Classification systems would also > > not be hard-wired if we really don't want to make programmers > > glorified data entry clerks. People, places, things, and categories > > will be entered by domain experts, not programmers for the most part. > > Fair enough. > What does the SQL solution that was posted now look like without > "hard-wired" schema information ?? I wanted to settle on a less "puzzly" version of the example so that I could explore this issue of how "meta" it would need to be. If it is a Simula-like problem, as described in a sister message, then perhaps a database is not appropriate. But I am not a physical simulation expert and thus could not really give an informed answer for that domain. > > > > It always seemed to me that if you remove domain classification from > > app code, the result will not be very OOP. There would be little or no > > need for inheritence or polymorphism. If you disagree, I would like to > > understand why, with perhaps some examples. > > An OO impl of a FOPL engine, vs a "P/R" one. > It will be interesting to see your implementation of such an engine. FOPL? Functional? > > > Regards, > Steven Perryman -T- |
|
#7
| |||
| |||
| topmind wrote: > Kreeg wrote: >> topmind wrote: >>> Jordan Marr wrote: >>>> I never posted my solution to Whose Fish, and since my old thread >>>> probably has a stigma attached to it, I'll post it here. >> ** SNIP Jordan's original post ** *SNIP* > >> However, an inference engine would certainly be an interesting way of >> solving the problem, I think. > > Perhaps that would just be reinventing Prolog :-) > **SNIP ** >> >> The most interesting piece of this problem IMO is not how the houses, >> people, and streets get entered, but how the program goes about finding >> the correct answer given sets of these things and a set of rules. > > Again, It would be interesting to see a Prolog solution in the sense > you tell it the logic rules and then ask questions over those rules. > I agree. I personally couldn't provide a Prolog implementation because I've never used it, but I would think that an implementation using any Rules Engine would be similar. Or did I mis-read the Wikipedia article on Prolog that I had to look up? :-P >>> It always seemed to me that if you remove domain classification from >>> app code, the result will not be very OOP. There would be little or no >>> need for inheritence or polymorphism. If you disagree, I would like to >>> understand why, with perhaps some examples. >>> >> Heck, Jordan's solution has very little inheritance or polymorphism. >> That doesn't mean I don't think it's a perfectly valid approach. > > My comment was about the matter of being OO versus not being OO, not > necessarily "valid" or not. Jordan's solution is not that OO. It > mostly only uses encapsulation, not the other two. That is, the > operations and data structures are bound together in the OO "self- > handling-noun" way. Thus, on a continious scale, it has a fairly low > amount of "OO-ness" if you will. > This is true. It actually gets back to Steven Perryman's comment to you that you that you would be 'pleasantly surprised' to see that OO probably doesn't add much to this particular problem over a straight procedural solution. I'd also be pretty interested in a solution that used C# 3.0's LINQ. There are some pretty neat things that have been done with LINQ just for the fun of it. [2] [2] http://blogs.msdn.com/lukeh/archive/...-in-c-3-0.aspx >> [1] http://groups.google.com/group/comp....c9e241f760a89a > > -T- > |
|
#8
| |||
| |||
| topmind wrote: > S Perryman wrote: TM>I was thinking of a way to make this problem more real-world instead TM>of textbook-puzzle-ish. One possible application would be crime TM>solving, or perhaps terrorist tracking. >>You were told by me, last month, that the problem had real world >>application in anti-terrorist intelligence (posted on May 10th) . > I don't recall that, but if that was the case, then why not *present* > an anti-terrorism problem, and give some sample scenarios? That way we > don't *have to* deal with a text-book-puzzle-like problem. Cut out > the middle-man. It is you who wants to make the problem different. Everyone else seems quite happy with the original problem. So feel free to redefine the problem in *any form that you wish to make* . >>Can you guess what your reply (posted on May 22nd) was to this fact ... ?? > Nope. Let's hope it won't embarass me, however :-) Forelorn hope (and quite embarrassing) . TM>(Instead of "who has the fish", the questions may resemble, "who may have a bomb".) >>Feel free to change the example (and all the facts) to something else. > Okay, how about a payroll example! Fine. Provide a payroll-based version of the "Whose fish" problem. I expect the 'question' to be something akin to : Who is not required to pay union dues for the rest of the year because of their contributions made to date ?? And facts akin to : union-member(fred) >>I would suggest going to the site from where the "Whose fish" example came. >>IIRC the site had a collection of similar problems. One of those may save >>you the effort of having to construct a "real world" example. > It is not my job to cull problems to present to comp.object. I already > did a few and posted the source code on the web. Nobody has shown it > objectively worse than Martin's version(s). 1. Robert Martin AFAIK has not provided an implementation of the "Whose fish" problem. If I am mistaken, feel free to tell us where his impl may be found. 2. You want to discuss a "terrorist" variant of the problem, but you don't want to provide the information that will enable that variant to be defined. (Predictably) lazy. 3. You have been directed to a site that may have examples that you can quickly convert into a problem that you wish to make, thus saving you time/ effort. But you don't want to do even that. (Predictably) lazy. >>What does the SQL solution that was posted now look like without >>"hard-wired" schema information ?? > I wanted to settle on a less "puzzly" version of the example so that I > could explore this issue of how "meta" it would need to be. As "meta" as one desires. The SQL and OOP solutions solved the specific problem. If you wish to change the problem to one where any facts can be stated, and any question can be asked, feel free to do so. >>An OO impl of a FOPL engine, vs a "P/R" one. >>It will be interesting to see your implementation of such an engine. > FOPL? Functional? First-order predicate logic. Actually the problem is FOPL, with CWA ( "closed world assumptions" ) . Regards, Steven Perryman |
|
#9
| |||
| |||
| > > Heck, Jordan's solution has very little inheritance or polymorphism. > > That doesn't mean I don't think it's a perfectly valid approach. > My comment was about the matter of being OO versus not being OO, not > necessarily "valid" or not. Jordan's solution is not that OO. It > mostly only uses encapsulation, not the other two. That is, the > operations and data structures are bound together in the OO "self- > handling-noun" way. Thus, on a continious scale, it has a fairly low > amount of "OO-ness" if you will. A "direct" procedural solution would > not be much different except that the data structures would be > "naked". (Whether this is good or not will take us back to the ol' > database versus app-RAM fights.) Inheritance allows my noun entities (house & street) to adopt the validation rule functionality from EntityBase. EntityBase, while not shown here, is composed of a few other custom classes, and delegates some behavior to them. There is also a hierarchy of Rule object defined that allows me to enter rules with or without "groups". Polymorphism is used here, behind the scenes, because my BrokenRule engine works with Rule objects, but it doesn't know or care what kind of Rule it is using. So if I am creating an entity with 20+ validation rules, I may want the ability to display a list of broken rules by group. If so, I add GroupRule objects instead, using the "AddGroupRule" method on EntityBase. The fact that all that is encapsulated away makes the final app code and entity code all the more simple. All you see is "AddRule(...)" or "AddGroupRule(...)" in the Entity code. Or for that matter, I have a generic AddRule that simply takes a Rule object (of any kind). AddRule(new GroupRule(...)). So Polymorphism is available behind the scenes, but is encapsulated away, out of sight. It is not used in the application portion of the example (it wasn't required). However, I don't think there is any rule that says an OO program must incorporate all of these features to be considered OO. Those features are simply there if you need them for a given problem. Jordan |
|
#10
| |||
| |||
| Jordan Marr wrote: >>> Heck, Jordan's solution has very little inheritance or polymorphism. >>> That doesn't mean I don't think it's a perfectly valid approach. > > >> My comment was about the matter of being OO versus not being OO, not >> necessarily "valid" or not. Jordan's solution is not that OO. It >> mostly only uses encapsulation, not the other two. That is, the >> operations and data structures are bound together in the OO "self- >> handling-noun" way. Thus, on a continious scale, it has a fairly low >> amount of "OO-ness" if you will. A "direct" procedural solution would >> not be much different except that the data structures would be >> "naked". (Whether this is good or not will take us back to the ol' >> database versus app-RAM fights.) > > Inheritance allows my noun entities (house & street) to adopt the > validation rule functionality from EntityBase. EntityBase, while not > shown here, is composed of a few other custom classes, and delegates > some behavior to them. There is also a hierarchy of Rule object > defined that allows me to enter rules with or without "groups". > Polymorphism is used here, behind the scenes, because my BrokenRule > engine works with Rule objects, but it doesn't know or care what kind > of Rule it is using. So if I am creating an entity with 20+ > validation rules, I may want the ability to display a list of broken > rules by group. If so, I add GroupRule objects instead, using the > "AddGroupRule" method on EntityBase. The fact that all that is > encapsulated away makes the final app code and entity code all the > more simple. > All you see is "AddRule(...)" or "AddGroupRule(...)" in the Entity > code. Or for that matter, I have a generic AddRule that simply takes > a Rule object (of any kind). AddRule(new GroupRule(...)). > Ah, I missed the rule-handling part. I like the use of delegates there, actually. > So Polymorphism is available behind the scenes, but is encapsulated > away, out of sight. It is not used in the application portion of the > example (it wasn't required). However, I don't think there is any > rule that says an OO program must incorporate all of these features to > be considered OO. Those features are simply there if you need them > for a given problem. > > Jordan > |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.