/*
--- CSU213 Spring 2005 Lecture Notes ---------
Copyright 2005 Viera K. Proulx

Lecture 14: Three Questions
*/

/* 
Goals:

 - learn to abstract class behavior using interfaces
 - learn to use interface as a type

Introduction:
We will be working with a class of books. Each book has an author,
year of publication, and a price. We would like to answer the
following questions about various lists of books:

A1: Is there a            book  in this list that is written by the "MF"?
B1: Are all the           books in this list written by "MF"?
C1: Produce a list of all books in this list written by "MF".

A2: Is there a            book  in this list that was published before 1980?
B2: Are all the           books in this list published before 1980?
C2: Produce a list of all books in this list published before 1980.

A3: Is there a            book  in this list that costs more that $10?
B3: Are all the           books in this list that cost more that $10?
C3: Produce a list of all books in this list that cost more that $10.

We can clearly see several patterns in these questions. All the 'A' questions
inquire whether there is at least one item with the given property. All the 
'B' question question whether all items in the list satisfy the given
property. Finally, the question 'C' is really a request to extract from the 
list only those items that satisfy the given property.

We start with designing the classes to represent books and lists of books.
The class diagram is shown here - the code appears at the end, toghether
with examples.

           +------+               
           | ALoB |<-------------+
           +------+              |
           +------+              |
              / \                |
              ---                |
               |                 |
      ----------------           |
      |              |           |
  +-------+    +------------+    |
  | MTLoB |    | ConsLoB    |    |
  +-------+    +------------+    |
  +-------+  +-| Book first |    |
             | | ALoB rest  |----+
             | +------------+ 
             |
             v
    +---------------+
    | Book          |
    +---------------+
    | String author |
    | int year      |
    | int price     |
    +---------------+

We start with examples of books and lists of books.


Book b1 = new Book("MF", 2001, 60);
Book b2 = new Book("EX", 1942, 15);
Book b3 = new Book("JL", 1900, 8);
Book b4 = new Book("MF", 1998, 15);

ALoB mtlist = new MTLoB();
ALoB list1 = new ConsLoB(b1, new ConsLoB(b4, mtlist));
ALoB list2 = new ConsLoB(b3, mtlist);
ALoB list3 = new ConsLoB(b2, new ConsLoB(b3, mtlist));
ALoB list4 = new ConsLoB(b1, new ConsLoB(b4, new ConsLoB(b3, mtlist)));
ALoB list5 = new ConsLoB(b2, new ConsLoB(b3, list1));

We can make examples for all questions:

A1: true for list1, false for list2, false for mtlist
B1: true for list1, false for list5, true for mtlist
C1: from list 5 produces list 1

A2: true for list5, false for list1, false for mtlist
B2: true for list3, false for list5, true for mtlist
C2: from list4 produces list3 

A3: true for list1, false for list2, false for mtlist
B3: true for list3, false for list4, true for mtlist
C3: for list4 produces list1

We will start with methods for the questions A1, A2, and A3.
For the empty list the answer is always 'false'. We can write
the purpose statement header for the class ALoB and the body 
for the class MTLoB:

In the class ALoB:

  // is there a book written by "MF" in this list?
  abstract boolean anyBookWrittenByMF();

  // is there a book published before 1980 in this list?
  abstract boolean anyBookBefore1980();

  // is there a book that costs more than $10 in this list?
  abstract boolean anyBookMoreThan10();

In the class MTLoB:

  boolean anyBookWrittenByMF(){ return false; }

  boolean anyBookBefore1980(){ return false; }

  boolean anyBookMoreThan10(){ return false; }

The template for the class ConsLoB contains the following:

   ... this.first ...
   ... this.rest ...
   ... this.rest.anyBookWrittenByMF() ...
   ... this.rest.anyBookBefore1980() ...
   ... this.rest.anyBookMoreThan10() ...

However, to complete the bodies of these three methods, we need
to add to the class Book the methods that determine whether this
book was written by "MF", or whether this book was published before
1980, or whether this book costs more than $10. Following the 
design recipe we end up with:

  // is this book written by "MF"
  boolean writtenByMF(){
    return this.author.equals("MF");
  }

  // was this book published before 1980
  boolean before1980(){
    return this.year < 1980;
  }

  // does this book cost more than $10
  boolean moreThan10(){
    return this.price > 10;
  }

The examples are iuncluded in the class Examples.
But that means, we can extend the template by the following:

   ... this.first.writtenByMF() ...
   ... this.first.before1980() ...
   ... this.first.moreThan10() ...

and finish the bodies of the methods in  the class ConsLoS:

  boolean anyBookWrittenByMF(){ 
    return this.first.writtenByMF()
        || this.rest.anyBookWrittenByMF();
  }

  boolean anyBookBefore1980(){ 
    return this.first.before1980()
        || this.rest.anyBookBefore1980();
  }

  boolean anyBookMoreThan10(){ 
    return this.first.moreThan10()
        || this.rest.anyBookMoreThan10();
  }

We see, that if we changes the names of the three methods to 
a common name (e.g. anyBookSuch), the only place where they 
differ is in determining whether this.first book satisfies
the predicate. We would like to abstract over this part and 
pass it to the method anyBookSuch as an argument.

There are two problems to overcome. The way the question
is written in our body requires that the methods writtenBy,
before1980, and moreThan10 are defined in  the class Book.
But if the methods are to have the same name, they cannot
be defined in the same class. Furthermore, we can only pass
an instnce of a class as an argument to a method. This leads
us to consider to have three different classes, each with the
method that determines whether a book satisfies the specific
predicate. Here is the method purpose statement and the header:

  // determine whether the given book satisfies a condition
  boolean selectBook(Book b){...}

However, to define an argument for our method anyBookSuch, we
need to specify its type. The instances of our three classes 
need to have some unifying type. One option os for all three 
classes to extend a common superclass. We will see later why 
that may not be the best option. The other option is for all
three classes to iimplement a common interface. This option
makes it clear that we aim to represent commmon behavior.

So, the interface is:

interface ISelectBook{
  // determine whether the given book satisfies a condition
  boolean selectBook(Book b);
}

And the three classes will be:

class WrittenByMF implements ISelectBook{
  // was the given book written by "MF"
  boolean selectBook(Book b){
    return b.author.equals("MF");
  }
}

class Before1980 implements ISelectBook{
  // was the given book published before 1980
  boolean selectBook(Book b){
    return b.year < 1980;
  }
}

class MoreThan10 implements ISelectBook{
  // does the given book cost more than $10
  boolean selectBook(Book b){
    return b.price > 10;
  }
}

We can now define the method anyBookSuch as follows:

In the class ALoB:

  // is there a book that satisfies the condition?
  abstract boolean anyBookSuch(ISelectBook choose);

In the class MTLoB:

  boolean anyBookSuch(ISelectBook choose){ return false; }

In the class ConsLoB:

  boolean anyBookSuch(ISelectBook choose){
    return choose.selectBook(this.first)
        || this.rest.anyBookSuch(choose);
  }

Finally, we rerun the original tests using the method anyBookSuch
with the appropriate arguments.

Part 2: Extensions

The methods we defined for selecting books are rath er limited. 
We canonly select one specific author, one specific publication 
date limit, or one base price. But this is easily remedied by 
adding a field to the classes that implement the 'selectBook' 
method as follows:

class WrittenBy implements ISelectBook{
  String author;

  WrittenBy(String author){
    this.author = author;
  }

  boolean selectBook(Book b){
    return b.author.equals(this.author);
  }
}

The test cases will become:

  // tests for the method anyBookWrittenBy
  boolean testAnyBookWrittenBy1a = 
          mtlist.anyBookSuch(new WrittenBy("MF")) == false;
  boolean testAnyBookWrittenBy2a = 
          list1.anyBookSuch(new WrittenBy("MF")) == true;
  boolean testAnyBookWrittenBy3a = 
          list2.anyBookSuch(new WrittenBy("MF")) == false;

Exercise:
Design the classes Before and MoreThan that allow us to select 
a book published before a specified date, or a book that costs 
more than a specified price. Make sure you run again the examples 
using the new function objects.


Part 3: Scheme Loops

Let us step back and think about the method we just designed. 
It determines whether there is an item in a list that satisfies 
the given predicate. This corresponds to the Scheme the loop 'ormap'. 
Here is the description of ormap:

;; ormap: (X -> boolean)(Listof X) -> boolean
;; to determine whether p holds for at least one item on alox
;; that is, (ormap p (list x-1 ... x-n)) = (or (p x-1) (or ... (p x-n)))
(define (ormap p alox) ... )

Our (Listof X) is the list of books that invokes the method anyBookSuch, 
the function (X -> boolean) is encapsulated in the function objects 
that implement ISelectBook that we pass to our method, and our result 
is boolean, the same as for the 'ormap'. 

Exercises:
Figure out which Scheme loops correspond to questions B and C.

Design the methods that solve the problems B1, B2, and B3, and abstract
them into the corresponding Scheme loop.

Do the same for the methods needed to solve the problems C1, C2, C3.

In the last part we need to compare two lists for extensional equality.
We will learn in the next lecture how to design such tests.

*/

/*
;                                     
;                                     
;                                     
;      ;     ;              ;;;;;     
;      ;     ;              ;    ;    
;     ; ;    ;              ;    ;    
;     ; ;    ;       ;;;    ;   ;     
;    ;   ;   ;      ;   ;   ;;;;      
;    ;   ;   ;     ;     ;  ;   ;     
;   ;;;;;;;  ;     ;     ;  ;    ;    
;   ;     ;  ;     ;     ;  ;    ;    
;   ;     ;  ;      ;   ;   ;    ;    
;  ;       ; ;;;;;;  ;;;    ;;;;;     
;                                     
;                                     
;                                     
*/
// to represent a list fo books
abstract class ALoB {

  // is there a book written by "MF" in this list?
  abstract boolean anyBookWrittenByMF();

  // is there a book published before 1980 in this list?
  abstract boolean anyBookBefore1980();

  // is there a book that costs more than $10 in this list?
  abstract boolean anyBookMoreThan10();

  // is there a book that satisfies the condition?
  abstract boolean anyBookSuch(ISelectBook choose);

/*
  // ** DRAFT TEMPLATE ** Edit as needed.
  // purpose statement 
  abstract ??? mmm();
*/
}

/*
;                                               
;                                               
;                                               
;   ;       ; ;;;;;;;  ;              ;;;;;     
;   ;;     ;;    ;     ;              ;    ;    
;   ;;     ;;    ;     ;              ;    ;    
;   ; ;   ; ;    ;     ;       ;;;    ;   ;     
;   ; ;   ; ;    ;     ;      ;   ;   ;;;;      
;   ;  ; ;  ;    ;     ;     ;     ;  ;   ;     
;   ;  ; ;  ;    ;     ;     ;     ;  ;    ;    
;   ;   ;   ;    ;     ;     ;     ;  ;    ;    
;   ;   ;   ;    ;     ;      ;   ;   ;    ;    
;   ;       ;    ;     ;;;;;;  ;;;    ;;;;;     
;                                               
;                                               
;                                               
*/
// to represent an empty list fo books
class MTLoB extends ALoB {

  MTLoB() {
  }

  boolean anyBookWrittenByMF(){ return false; }

  boolean anyBookBefore1980(){ return false; }

  boolean anyBookMoreThan10(){ return false; }

  boolean anyBookSuch(ISelectBook choose){ return false; }

/*
  // ** DRAFT TEMPLATE ** Edit as needed.
  ??? mmm() {
  }
*/
}

/*
;                                                            
;                                                            
;                                                            
;     ;;;;                          ;              ;;;;;     
;    ;    ;                         ;              ;    ;    
;   ;                               ;              ;    ;    
;   ;         ;;;    ; ;;     ;;;   ;       ;;;    ;   ;     
;   ;        ;   ;   ;;  ;   ;      ;      ;   ;   ;;;;      
;   ;       ;     ;  ;   ;   ;;     ;     ;     ;  ;   ;     
;   ;       ;     ;  ;   ;    ;;    ;     ;     ;  ;    ;    
;   ;       ;     ;  ;   ;      ;   ;     ;     ;  ;    ;    
;    ;    ;  ;   ;   ;   ;      ;   ;      ;   ;   ;    ;    
;     ;;;;    ;;;    ;   ;   ;;;    ;;;;;;  ;;;    ;;;;;     
;                                                            
;                                                            
;                                                            
*/
// to represent a nonempty list fo books
class ConsLoB extends ALoB {
  Book first;
  ALoB rest;

  ConsLoB(Book first, ALoB rest) {
    this.first = first;
    this.rest = rest;
  }

  boolean anyBookWrittenByMF(){ 
    return this.first.writtenByMF()
        || this.rest.anyBookWrittenByMF();
  }

  boolean anyBookBefore1980(){ 
    return this.first.before1980()
        || this.rest.anyBookBefore1980();
  }

  boolean anyBookMoreThan10(){ 
    return this.first.moreThan10()
        || this.rest.anyBookMoreThan10();
  }

  boolean anyBookSuch(ISelectBook choose){
    return choose.selectBook(this.first)
        || this.rest.anyBookSuch(choose);
  }

/*
  // ** DRAFT TEMPLATE ** Edit as needed.
  ??? mmm() {
    ... this.first ...
    ... this.rest.mmm() ...
  }
*/
}

/*
;                                     
;                                     
;                                     
;   ;;;;;                  ;          
;   ;    ;                 ;          
;   ;    ;                 ;          
;   ;   ;   ;;;     ;;;    ;   ;      
;   ;;;;   ;   ;   ;   ;   ;  ;       
;   ;   ; ;     ; ;     ;  ; ;        
;   ;    ;;     ; ;     ;  ;;;        
;   ;    ;;     ; ;     ;  ;  ;       
;   ;    ; ;   ;   ;   ;   ;   ;      
;   ;;;;;   ;;;     ;;;    ;    ;     
;                                     
;                                     
;                                     
*/
// to represent a book
class Book {
  String author;
  int year;
  int price;

  Book(String author, int year, int price) {
    this.author = author;
    this.year = year;
    this.price = price;
  }

  // is this book written by "MF"
  boolean writtenByMF(){
    return this.author.equals("MF");
  }

  // was this book published before 1980
  boolean before1980(){
    return this.year < 1980;
  }

  // does this book cost more than $10
  boolean moreThan10(){
    return this.price > 10;
  }

/*
  // ** DRAFT TEMPLATE ** Edit as needed.
  ??? mmm() {
    ... this.author ...
    ... this.year ...
    ... this.price ...
  }
*/
}

/* 
;                                                                              
;                                                                              
;                                                                              
;   ;    ;;;;         ;                      ;;;;;                  ;          
;   ;   ;    ;        ;                      ;    ;                 ;          
;   ;   ;             ;                 ;    ;    ;                 ;          
;   ;   ;       ;;;   ;    ;;;    ;;;  ;;;;  ;   ;   ;;;     ;;;    ;   ;      
;   ;    ;;    ;   ;  ;   ;   ;  ;   ;  ;    ;;;;   ;   ;   ;   ;   ;  ;       
;   ;      ;  ;    ;  ;  ;    ; ;       ;    ;   ; ;     ; ;     ;  ; ;        
;   ;       ; ;;;;;;  ;  ;;;;;; ;       ;    ;    ;;     ; ;     ;  ;;;        
;   ;       ; ;       ;  ;      ;       ;    ;    ;;     ; ;     ;  ;  ;       
;   ;   ;   ;  ;      ;   ;      ;   ;  ;    ;    ; ;   ;   ;   ;   ;   ;      
;   ;    ;;;    ;;;;  ;    ;;;;   ;;;    ;;  ;;;;;   ;;;     ;;;    ;    ;     
;                                                                              
;                                                                              
;                                                                              
*/
interface ISelectBook{
  // determine whether the given book satisfies a condition
  boolean selectBook(Book b);
}

/*
;                                                                                   
;                                                                                   
;                                                                                   
;  ;    ;    ;      ;                            ;;;;;         ;       ;  ;;;;;     
;  ;    ;    ;                                   ;    ;        ;;     ;;  ;         
;  ;   ; ;   ;          ;    ;                   ;    ;        ;;     ;;  ;         
;   ;  ; ;  ;  ; ;  ;  ;;;; ;;;;   ;;;   ; ;;    ;   ; ;     ; ; ;   ; ;  ;         
;   ;  ; ;  ;  ;;   ;   ;    ;    ;   ;  ;;  ;   ;;;;  ;     ; ; ;   ; ;  ;;;;      
;   ; ;   ; ;  ;    ;   ;    ;   ;    ;  ;   ;   ;   ;  ;   ;  ;  ; ;  ;  ;         
;   ; ;   ; ;  ;    ;   ;    ;   ;;;;;;  ;   ;   ;    ; ;   ;  ;  ; ;  ;  ;         
;   ; ;   ; ;  ;    ;   ;    ;   ;       ;   ;   ;    ;  ; ;   ;   ;   ;  ;         
;    ;     ;   ;    ;   ;    ;    ;      ;   ;   ;    ;  ; ;   ;   ;   ;  ;         
;    ;     ;   ;    ;    ;;   ;;   ;;;;  ;   ;   ;;;;;    ;    ;       ;  ;         
;                                                         ;                         
;                                                         ;                         
;                                                        ;                          
*/
class WrittenByMF implements ISelectBook{
  // was the given book written by "MF"
  boolean selectBook(Book b){
    return b.author.equals("MF");
  }
}

/*
;                                                                             
;                                                                             
;                                                                             
;   ;;;;;          ;;;                       ;;      ;;     ;;;;     ;;       
;   ;    ;        ;                         ; ;     ;  ;   ;    ;   ;  ;      
;   ;    ;        ;                           ;    ;    ;  ;    ;  ;    ;     
;   ;   ;   ;;;  ;;;;   ;;;    ; ;   ;;;      ;    ;    ;   ;  ;   ;    ;     
;   ;;;;   ;   ;  ;    ;   ;   ;;   ;   ;     ;     ;  ;;    ;;    ;    ;     
;   ;   ; ;    ;  ;   ;     ;  ;   ;    ;     ;      ;; ;   ;  ;   ;    ;     
;   ;    ;;;;;;;  ;   ;     ;  ;   ;;;;;;     ;         ;  ;    ;  ;    ;     
;   ;    ;;       ;   ;     ;  ;   ;          ;         ;  ;    ;  ;    ;     
;   ;    ; ;      ;    ;   ;   ;    ;         ;        ;   ;    ;   ;  ;      
;   ;;;;;   ;;;;  ;     ;;;    ;     ;;;;   ;;;;;  ;;;;     ;;;;     ;;       
;                                                                             
;                                                                             
;                                                                             
*/
class Before1980 implements ISelectBook{
  // was the given book published before 1980
  boolean selectBook(Book b){
    return b.year < 1980;
  }
}

/*
;                                                                                    
;                                                                                    
;                                                                                    
;   ;       ;                     ;;;;;;;  ;                        ;;      ;;       
;   ;;     ;;                        ;     ;                       ; ;     ;  ;      
;   ;;     ;;                        ;     ;                         ;    ;    ;     
;   ; ;   ; ;   ;;;    ; ;   ;;;     ;     ; ;;    ;;;    ; ;;       ;    ;    ;     
;   ; ;   ; ;  ;   ;   ;;   ;   ;    ;     ;;  ;  ;   ;   ;;  ;      ;    ;    ;     
;   ;  ; ;  ; ;     ;  ;   ;    ;    ;     ;   ;      ;   ;   ;      ;    ;    ;     
;   ;  ; ;  ; ;     ;  ;   ;;;;;;    ;     ;   ;   ;;;;   ;   ;      ;    ;    ;     
;   ;   ;   ; ;     ;  ;   ;         ;     ;   ;  ;   ;   ;   ;      ;    ;    ;     
;   ;   ;   ;  ;   ;   ;    ;        ;     ;   ;  ;   ;   ;   ;      ;     ;  ;      
;   ;       ;   ;;;    ;     ;;;;    ;     ;   ;   ;;;;;  ;   ;    ;;;;;    ;;       
;                                                                                    
;                                                                                    
;                                                                                    
*/
class MoreThan10 implements ISelectBook{
  // does the given book cost more than $10
  boolean selectBook(Book b){
    return b.price > 10;
  }
}

/*
;                                                                 
;                                                                 
;                                                                 
;  ;    ;    ;      ;                            ;;;;;            
;  ;    ;    ;                                   ;    ;           
;  ;   ; ;   ;          ;    ;                   ;    ;           
;   ;  ; ;  ;  ; ;  ;  ;;;; ;;;;   ;;;   ; ;;    ;   ; ;     ;    
;   ;  ; ;  ;  ;;   ;   ;    ;    ;   ;  ;;  ;   ;;;;  ;     ;    
;   ; ;   ; ;  ;    ;   ;    ;   ;    ;  ;   ;   ;   ;  ;   ;     
;   ; ;   ; ;  ;    ;   ;    ;   ;;;;;;  ;   ;   ;    ; ;   ;     
;   ; ;   ; ;  ;    ;   ;    ;   ;       ;   ;   ;    ;  ; ;      
;    ;     ;   ;    ;   ;    ;    ;      ;   ;   ;    ;  ; ;      
;    ;     ;   ;    ;    ;;   ;;   ;;;;  ;   ;   ;;;;;    ;       
;                                                         ;       
;                                                         ;       
;                                                        ;        
*/
class WrittenBy implements ISelectBook{
  String author;

  WrittenBy(String author){
    this.author = author;
  }

  boolean selectBook(Book b){
    return b.author.equals(this.author);
  }
}

/*

                          + - - - - - - - - - - - +
                                                  | 
                          | 
                          v                       | 
            +----------------------------+
            | I: ISelectBook             |        |
            +----------------------------+
            | boolean selectBook(Book b) |        |
            +----------------------------+
                                                  |
        + - - - - - - - - + - - - - - - - + - - - + - - - - +
        |                 |               |                 |

        |                 |               |                 |
 +-------------+   +------------+   +------------+   +---------------+
 | WrittenByMF |   | Before1980 |   | MoreThan10 |   | WrittenBy     |
 +-------------+   +------------+   +------------+   +---------------+
 +-------------+   +------------+   +------------+   | String author |
                                                     +---------------+


*/

/*
;                                                                  
;                                                                  
;                                                                  
;   ;;;;;;                                    ;                    
;   ;                                         ;                    
;   ;                                         ;                    
;   ;     ;     ;  ;;;    ; ;;  ;;    ; ;;    ;    ;;;    ;;;      
;   ;;;;;  ;   ;  ;   ;   ;;  ;;  ;   ;;  ;   ;   ;   ;  ;         
;   ;       ; ;       ;   ;   ;   ;   ;    ;  ;  ;    ;  ;;        
;   ;        ;     ;;;;   ;   ;   ;   ;    ;  ;  ;;;;;;   ;;       
;   ;       ; ;   ;   ;   ;   ;   ;   ;    ;  ;  ;          ;      
;   ;      ;   ;  ;   ;   ;   ;   ;   ;;  ;   ;   ;         ;      
;   ;;;;;;;     ;  ;;;;;  ;   ;   ;   ; ;;    ;    ;;;;  ;;;       
;                                     ;                            
;                                     ;                            
;                                     ;                            
*/
class Examples{
  Examples(){}

  Book b1 = new Book("MF", 2001, 60);
  Book b2 = new Book("EX", 1942, 15);
  Book b3 = new Book("JL", 1900, 8);
  Book b4 = new Book("MF", 1998, 15);

  ALoB mtlist = new MTLoB();
  ALoB list1 = new ConsLoB(b1, new ConsLoB(b4, mtlist));
  ALoB list2 = new ConsLoB(b3, mtlist);
  ALoB list3 = new ConsLoB(b2, new ConsLoB(b3, mtlist));
  ALoB list4 = new ConsLoB(b1, new ConsLoB(b4, new ConsLoB(b3, mtlist)));
  ALoB list5 = new ConsLoB(b2, new ConsLoB(b3, list1));

  // tests for predicates in the class Book
  boolean testWrittenByMF1 = b1.writtenByMF() == true;
  boolean testWrittenByMF2 = b2.writtenByMF() == false;

  boolean testBefore1980t1 = b1.before1980() == false;
  boolean testBefore1980t2 = b2.before1980() == true;

  boolean testMoreThan10t1 = b1.moreThan10() == true;
  boolean testMoreThan10t2 = b3.moreThan10() == false;

  // tests for the method anyBookWrittenByMF
  boolean testAnyBookWrittenByMF1 = mtlist.anyBookWrittenByMF() == false;
  boolean testAnyBookWrittenByMF2 = list1.anyBookWrittenByMF() == true;
  boolean testAnyBookWrittenByMF3 = list2.anyBookWrittenByMF() == false;

  // tests for the method anyBookBefore1980
  boolean testAnyBookBefore1980t1 = mtlist.anyBookBefore1980() == false;
  boolean testAnyBookBefore1980t2 = list5.anyBookBefore1980() == true;
  boolean testAnyBookBefore1980t3 = list1.anyBookBefore1980() == false;

  // tests for the method anyBookMoreThan10
  boolean testAnyBookMoreThan10t1 = mtlist.anyBookMoreThan10() == false;
  boolean testAnyBookMoreThan10t2 = list1.anyBookMoreThan10() == true;
  boolean testAnyBookMoreThan10t3 = list2.anyBookMoreThan10() == false;

  // tests for the method anyBookWrittenByMF
  boolean testAnyBookWrittenByMF1a = mtlist.anyBookSuch(new WrittenByMF()) == false;
  boolean testAnyBookWrittenByMF2a = list1.anyBookSuch(new WrittenByMF()) == true;
  boolean testAnyBookWrittenByMF3a = list2.anyBookSuch(new WrittenByMF()) == false;

  // tests for the method anyBookBefore1980
  boolean testAnyBookBefore1980t1a = mtlist.anyBookSuch(new Before1980()) == false;
  boolean testAnyBookBefore1980t2a = list5.anyBookSuch(new Before1980()) == true;
  boolean testAnyBookBefore1980t3a = list1.anyBookSuch(new Before1980()) == false;

  // tests for the method anyBookMoreThan10
  boolean testAnyBookMoreThan10t1a = mtlist.anyBookSuch(new MoreThan10()) == false;
  boolean testAnyBookMoreThan10t2a = list1.anyBookSuch(new MoreThan10()) == true;
  boolean testAnyBookMoreThan10t3a = list2.anyBookSuch(new MoreThan10()) == false;

  // tests for the method anyBookWrittenBy
  boolean testAnyBookWrittenBy1a = mtlist.anyBookSuch(new WrittenBy("MF")) == false;
  boolean testAnyBookWrittenBy2a = list1.anyBookSuch(new WrittenBy("MF")) == true;
  boolean testAnyBookWrittenBy3a = list2.anyBookSuch(new WrittenBy("MF")) == false;

/*
  A1: true for list1, false for list2, false for mtlist
  B1: true for list1, false for list5, true for mtlist
  C1: from list 5 produces list 1


  A2: true for list5, false for list1, false for mtlist
  B2: true for list3, false for list5, true for mtlist
  C2: from list4 produces list3 

  A3: true for list1, false for list2, false for mtlist
  B3: true for list3, false for list4, true for mtlist
  C3: for list4 produces list1
*/

}


