Whose Fish - OO solution - Theory and Concepts

This is a discussion on Whose Fish - OO solution - Theory and Concepts ; 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 ...

+ Reply to Thread
Page 1 of 7 1 2 3 ... LastLast
Results 1 to 10 of 66

Whose Fish - OO solution

  1. Default Whose Fish - OO solution

    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. Default Re: Whose Fish - OO solution


    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. Default Re: Whose Fish - OO solution



    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. Default Re: Whose Fish - OO solution

    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. Default Re: Whose Fish - OO solution


    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. Default Re: Whose Fish - OO solution


    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. Default Re: Whose Fish - OO solution



    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. Default Re: Whose Fish - OO solution

    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. Default Re: Whose Fish - OO solution

    > > 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. Default Re: Whose Fish - OO solution



    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
    >


+ Reply to Thread
Page 1 of 7 1 2 3 ... LastLast

Similar Threads

  1. So long, and thanks for all the fish...
    By Application Development in forum basic.visual
    Replies: 5
    Last Post: 09-05-2007, 12:50 PM
  2. Whose Fish?
    By Application Development in forum Theory and Concepts
    Replies: 111
    Last Post: 06-04-2007, 10:04 AM
  3. Re: Fish Eye processing
    By Application Development in forum C
    Replies: 0
    Last Post: 05-31-2007, 06:08 PM
  4. Fish Lens Effect
    By Application Development in forum Adobe Tools
    Replies: 2
    Last Post: 09-05-2006, 03:47 PM
  5. Flailing Fish in Need Of Rescue
    By Application Development in forum PROLOG
    Replies: 0
    Last Post: 04-26-2006, 01:17 PM