Prolog-style pattern matching in Java. How to?

U

Ulrich Scholz

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
 
H

Hunter Gratzner

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.

You are about to write shitty Java programs. Either drop the "I want
to do it like in Prolog" attitude or stick with Prolog.
 
P

Patricia Shanahan

Ulrich said:
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?

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
 
U

Ulrich Scholz

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
 
P

Patricia Shanahan

Ulrich said:
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

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
 
H

Hunter Gratzner

Apply them in a loop:

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

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);
}
}
}
 
P

Patricia Shanahan

Hunter said:
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(...);
}
}
}

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
 
U

Ulrich Scholz

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

Thanks again for your helpful and constructive answers. I'll let them
sink in.

Ulrich
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top