Prolog-style pattern matching in Java. How to?

Discussion in 'Java' started by Ulrich Scholz, Aug 26, 2007.

  1. I enjoy programming (and thinking) in Prolog but the reality requires
    Java. Now I try to use the best of the former with the latter.
    Backtracking can be simulated in Java via enumerators so that seems to
    be no problem.

    But how to realize Prolog-style pattern matching? A gigant if-then-
    else of case construct is too complex and confusing; a solution via
    reflection seems to be unefficient.

    Any ideas, suggestions? Literature references?

    Thanks,

    Ulrich
     
    Ulrich Scholz, Aug 26, 2007
    #1
    1. Advertisements

  2. Ulrich Scholz

    Roedy Green Guest

    Roedy Green, Aug 26, 2007
    #2
    1. Advertisements

  3. You are about to write shitty Java programs. Either drop the "I want
    to do it like in Prolog" attitude or stick with Prolog.
     
    Hunter Gratzner, Aug 26, 2007
    #3
  4. My suggestion is to backtrack. You presumably have a problem you are
    trying to solve, for which Prolog backtracking and pattern matching is a
    local optimum. Now you want a Java solution, so you need to leave that
    point. Retaining the "Prolog-style pattern matching" idea limits the new
    search to a subspace of the Java program design space that somehow
    reproduces a Prolog design pattern.

    Maybe that subspace includes a really good Java solution to your
    problem. Maybe it doesn't. But without backtracking in your design
    thinking you will not be able to see if there is a better Java solution
    outside the "Java implementation of Prolog-style pattern matching" subspace.

    If you are going to code well in Java, not Prolog, you need to think in
    Java, not Prolog.

    Natural language translation provides another way of seeing this issue.
    Suppose I say "I am going to go to the movie theater that finds itself
    in the Westview shopping center". It is very stilted, awkward English.
    However, "that finds itself" is a literal translation of "qui se trouve"
    an idiom that sounds perfectly natural in French. You are in danger of
    writing, in Java, literal translations of Prolog idioms.

    Patricia
     
    Patricia Shanahan, Aug 26, 2007
    #4
  5. Thanks for your answers. You're probably right in saying that trying
    to program Prolog-style in Java will lead to bad programs.

    Nevertheless, I have a problem with many (~20) cases where any case
    that "matches" has to be considered. (More precisely, it's a fix
    point computation with an initial situation, which is extended each
    time a case "matches". But the kind of computation should not matter
    here.) "Matching" corresponds to the success of all of a small set of
    tests, like {a>5, t is the empty string, p is not null}.

    If you say: Don't do it the Prolog way, do it the Java way instead:
    What is the Java way?

    Ulrich
     
    Ulrich Scholz, Aug 26, 2007
    #5
  6. I'm not sure I understand your problem well enough for a complete
    solution, but here is one idea of how I might approach it. Even if this
    is not right for your problem, it may give you some bits and pieces of
    ideas that help.

    interface Matcher{
    boolean matches(int a, String t, Object p);
    }

    Obviously, the parameters are just examples. Possibly there is some
    object describing the current solution.

    Then write an array of Matcher objects:

    Matcher example1 = new Matcher(){
    public boolean matches(int a, String t, Object p){
    return a>5 && "".equals(t) && p != null;
    }
    }

    Matcher example2 = new Matcher(){
    public boolean matches(int a, String t, Object p){
    return a>=42;
    }
    }


    Stick references to these in an array or List:

    Matcher[] allMatchers = {
    example1,
    example2,
    someOtherMatcher,
    ....
    };

    Apply them in a loop:

    for(Matcher m: allMatchers){
    if(m.matches(whatever parameters)){
    // Deal with a hit
    }
    }

    Patricia
     
    Patricia Shanahan, Aug 26, 2007
    #6
  7. Better, let the "matcher" deal with the hit => Visitor


    interface Visitor {
    public void visit(Computation c);
    }

    Visitor example1 = new Visitor() {
    public void visit(Computation c) {
    if(c.getA() > 5 && "".equals(c.getT()) && c.getP() != null) {
    // manipulate Computation c in some way
    // c.setX(...); c.setY(...);
    }
    }
    }

    ....

    class Computation {
    protected Visitor[] computationManipulators = {
    example1, ..., ...
    }

    public void accept(Visitor v) {
    v.visit(this)
    }

    public int getA() { return a; };
    public String getT() { return T; }
    public Object getP() { return p; }

    public void manipulate() {
    for(Visitor v: computationManipulators) {
    accept(v);
    }
    }
    }
     
    Hunter Gratzner, Aug 26, 2007
    #7
  8. I would make the choice between the two approaches depending on how the
    reaction to a match depends on the pattern. If there is a fixed
    reaction, then the matcher should just decide whether there is a match.
    If a match condition and a reaction to it are logically coupled, then
    the visitor pattern is better.

    Patricia
     
    Patricia Shanahan, Aug 26, 2007
    #8
  9. Thanks again for your helpful and constructive answers. I'll let them
    sink in.

    Ulrich
     
    Ulrich Scholz, Aug 27, 2007
    #9
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.