----------------------
PIANO FINGERING Domain
----------------------

Thomas Burg,   TBURG@MAX.U.WASHINGTON.EDU
               c473bg

0. Comment on this README file
------------------------------
The README file for Project, phase 2 has been renamed to README-DOC.
It (still) contains crucial part of the documentation for the domain.

THIS file answers the questions from the handout.

1. Question 1
-------------
(a)
First I'd like to comment on the nature of the problem:
1) It is absolutely trivial to come up with 'A' solution
2) It is absolutely impossible to decide which is 'THE BEST' solution
3) It is absolutely non-trivial to come up with a 'GOOD' solution
4) It is non-trivial to decide, if a solution is 'GOOD'
5) In my state of knowledge, I am not always able to solve task 3)

By implementing a 'cost-model' for playing a piece, the author tried 
to approach problem 4).

With SCRs it is - in principle - possible to solve problem 3).

The problem is COMPLEX. 

The problem is DIFFERENT than many of the problems we talked about in
class. It DOES consist of a BIG search tree, however it cannot be solved
by search techniques alone because of 2). Still, with the idea of the
cost-function I think it can be approached fruitfully with prodigy.

The author thinks that the way he implemented the domain is NOT the
usual way to solve a problem in PRODIGY: The search itself is pretty
straightforward, there is NO subgoaling going on. We always have a
SINGLE goal we are working on, I don't think one should call the 
search we do here MEA. 
The author would rather talk of a 'best-first-search with backtracking'.
(For further somments see README-DOC).

Now I feel ready to comment on aspects not realized in the domain:
- The Operators (= allowed and possible actions) represent only a subset
  of the possibilities of a piano player. There are lots of more moves,
  however, they could all be implemented in the same way.
- We are limited to the use one hand. For many pieces, this is no big problem
  as one hand cares for the melody, the other for the harmonization.
  (The problem is 'decomposable').
  However, there are pieces in which the melody changes hands...
- We are limited in playing pieces within a given scale, so we cannot play 
  single accidentals.
  This is a major drawback of the approach, in principle it should be 
  possible to overcome it. But then we would have to think harder about
  relationships as NEXT-NOTE.
- The 'cost-function' is a very simple one. One could try to put more
  effort in it and to make it related to the scale we are in.
  The author still thinks a simple function is OK.
  What we cannot avoid is: Moves not implemented in the domain used
  in a solution supplied by a human would make it difficult to evaluate
  its cost. Using the given operators to imitate the solution will
  result in a poor evaluation for sure.
- Finally there is MUCH MORE meta-knowledge than the author could put
  in within the given time. He spent an awful amount of time trying to
  get SCRs working (especially writing a meta-fnc looking in the goal
  state was a lot of fun...).
  However: With the possibilities now
  (access to the notes played so far and the notes to be played in the
   future) it is no big problem to implement more meta-knowledge.
  An important issue would be:
  "Standard fingering": For each scale there is a standard fingering
  and we could try to PREFER those operators which comply with it.
  We would have to put the scale we are in in the state (easy) and to
  write scale-dependant meta-rules (easy, but lot of work).
  (In a very late effort, 4 rules like this have been implemented, see
   README-DOC, 8.4.)


Because of the nature of the problem and the way it was implemented,
we do not have any subgoal interleaving.

(b)
The author thought, it would be difficult to implement the ORDERED aspect of
the goal-state (all note played in order). It was 'easy' though by modifying
the SCR SELECT-FIRST-GOAL and by adding a counter.

Same holds for the 'Cost-evaluating function'.

Both wasn't easy, because the author spend a lot of time trying to get
counters etc. going with static predicates, which turned out to be
impossible for him in the first phase of the project.

With his improved knowledge of SCR's it might be possible to avoid subgoaling
on static generators, but what's the use then ? (Later comment: It is 
possible and still take a lot of time, so it wasn't done. Non-static
generators used instead...)

(c)
Of course all of them. The author liked SCFAIL and OPFAIL and the ANALYZE
facility in general.

(d)
Even if the author liked SCFAIL and OPFAIL he would have liked it even more,
if they would print out the names of the failed SCRs / OPs.

How about the possibility to access EVERY note in the analyze facility.
Of course there is BACKTRACK, but it did not even work once when the author
tried...

Finally: The trace would be
-less readable                  but maybe
-more useful 
if the output format would be shortened. Maybe a switch like
COMPRESS-TRACE [level] ?

I wonder if it would be possible to implement a possibility to avoid
subgoaling in the preconds. My view of cause is limited to my domain,
but I can think of many cases (Counters, ...) in which we don't want
to subgoal. So a syntax like

(preconds
  (AND
    (object <ob>)            ;static generator
    (has-hole <ob>)          ;predicate, will be subgoaled on
    (known (thumb <note>))   ;just a quick look in the state ...
  ...))

would be really nice and might avoid some confusion as well...