FINAL COM 1205                                  Winter 2003
Karl Lieberherr
Software Design and Development
========================================================================

Open book and open notes

1:	23 points  parsing, printing, 3-way pattern matching
2: 	52 points  write semantic checker
3: 	21 points  Don't Repeat Yourself Principle
4:	33 points  predict output of program
5: 	20 points  class dictionary design
       ---
       149 points

If there are multiple correct answers for a question, make a note.

The following class dictionary is used in questions
1 through 5.

import edu.neu.ccs.demeter.dj.*;
import java.util.*;

Main = .

Input = "cds" <cds> List(Cd) 
  "glue" CdGlue 
  "traversals" <travs> List(Traversal) EOF.
Cd = <cdName> CdName <classDefs> List(ClassDef).
ClassDef = <n> ClassName <parts> List(Part).
Part = PartName ClassName.

CdGlue = <correspondences> List(Corresp).
Corresp= <first> QualifiedClass "=" <second> QualifiedClass.
QualifiedClass = CdName "." ClassName.

Traversal = TraversalName List(Seg).
Seg = "in" CdName "from" <from1> ClassName "to" <to1> ClassName.


CdName = Ident.
ClassName = Ident.
PartName = Ident.
TraversalName = Ident.
List(S) ~ "(" {S} ")".

Question 1:
===========
23 UNKNOWNs: 1 point each
1:	23 points 

Consider the following input and object graph:
Find the UNKNOWNs.

input:
============================================================

cds
(
  UNKNOWN1 
    UNKNOWN2
      UNKNOWN3 ( UNKNOWN4 B c C )
      B ( )
      C ( )
    )
  Y 
    (
      C ( b B)
      B ( e E)
      E ( )
    )
)
glue
(
  X.C = Y.C 
)
traversals
(
  t1 (
    in X from A to C
    in Y from C to E
  )
)


object graph:
============================================================

: Input  (
 <cds> : Cd_List  {
  <first> : Nonempty_Cd_List  (
   <it> : Cd  (
    <cdName> : CdName  (
     <ident>  : Ident "X" )
    <classDefs> : ClassDef_List  {
     <first> : Nonempty_ClassDef_List  (
      <it> : ClassDef  (
       <n> : ClassName  (
        <ident>  : Ident "A" )
       <parts> : Part_List  {
        <first> : Nonempty_Part_List  (
         <it> : Part  (
          <partname> : PartName  (
           <ident>  : Ident "b" )
          <classname> : ClassName  (
           <ident>  : Ident "B" ) )
         <next> : Nonempty_Part_List  (
          <it> : Part  (

// several lines omitted

 <cdglue> : CdGlue  (
  <correspondences> : Corresp_List  {
   <first> : Nonempty_Corresp_List  (
    <it> : UNKNOWN5  (
     <first> : UNKNOWN6  (
      <UNKNOWN7> : UNKNOWN8  (
       <UNKNOWN9>  : UNKNOWN10 )
      <UNKNOWN11> : UNKNOWN12  (
       <UNKNOWN13>  : UNKNOWN14 ) )
     <second> : UNKNOWN15  (
      <cdname> : CdName  (
       <ident>  : Ident "Y" )
      <classname> : ClassName  (
       <ident>  : Ident "UNKNOWN16" ) ) ) ) } )
 <travs> : Traversal_List  {
  <first> : Nonempty_Traversal_List  (
   <it> : Traversal  (
    <traversalname> : TraversalName  (
     <ident>  : Ident "UNKNOWN17" )
    <seg_list> : Seg_List  {
     <first> : Nonempty_Seg_List  (
      <it> : Seg  (
       <cdname> : CdName  (
        <ident>  : Ident "UNKNOWN18" )
       <from1> : ClassName  (
        <ident>  : Ident "UNKNOWN19" )
       <to1> : ClassName  (
        <ident>  : Ident "UNKNOWN20" ) )
      <next> : Nonempty_Seg_List  (
       <it> : Seg  (
        <cdname> : CdName  (
         <ident>  : Ident "UNKNOWN21" )
        <from1> : ClassName  (
         <ident>  : Ident "UNKNOWN22" )
        <to1> : ClassName  (
         <ident>  : Ident "UNKNOWN23" ) ) ) ) } ) ) } ) 


Question 2:
===========
13 UNKNOWNs, 4 points each
2: 	52 points

Write a program that checks that all the CdName-objects
that are used in the glue part or the traversals part
of an Input-object are 
defined in  the cds part of the same Input-object.
Your program must print "true" or "false".

Use the "containsAll" method of interface Collection:

boolean containsAll(Collection c) 
	  Returns true if this collection 
	  contains all of the elements 
	  in the specified collection c. 

The class graph object of class ClassGraph is available
in variable cg. Find the UNKNOWNs below.
The Input object is in variable i.

    List defined = UNKNOWN1.UNKNOWN2(i,
      " from UNKNOWN3 " +
	UNKNOWN4 +
	" via UNKNOWN5 " +
      " to edu.neu.ccs.demeter.Ident"); 
    List used = UNKNOWN6.UNKNOWN7(i,
      " from UNKNOWN8 " +
	UNKNOWN9 +
	" via UNKNOWN10 " +
      " to edu.neu.ccs.demeter.Ident"); 
    System.out.println(UNKNOWN11.UNKNOWN12(UNKNOWN13));


Question 3:
===========
7 UNKNOWNs, 3 points each
3: 	21 points

Consider the following two methods gather1 and gather2 that violate
the DRY principle:

  List gather1(ClassGraph cg){
    List l1 = cg.gather(this, 
      "from Input via Traversal " + 
	  "via -> *,from1,* " + 
	  "via ClassName to edu.neu.ccs.demeter.Ident");
    l1.remove(0);
    System.out.println(l1.toString());
    System.out.println(" done gather 1 ");
    return(l1);
  }
  List gather2(ClassGraph cg){
    List l2 = cg.gather(this, 
      "from Input via Traversal " + 
	  "via -> *,to1,* " + 
	  "via ClassName to edu.neu.ccs.demeter.Ident");
    l2.remove(l2.size()-1);
    System.out.println(l2.toString());
    System.out.println(" done gather 2 ");
    return(l2);
  }

Write a new method gather that follows the DRY principle:
Find the UNKNOWNs below.

  List gather(ClassGraph cg, UNKNOWN1 UNKNOWN2, UNKNOWN3 UNKNOWN4){
    List l = cg.gather(this,
      "from Input via Traversal " + 
	  UNKNOWN5 +
	  "via ClassName to edu.neu.ccs.demeter.Ident");
    UNKNOWN6
    System.out.println(l.toString());
    System.out.println(" done gather " + kind);
    return(l);
  }

How will you replace the two calls

    List l1 = i.gather1(cg2);
    List l2 = i.gather2(cg2);

by two calls to gather? Put your answer in UNKNOWN7.


Question 4:
===========
11 UNKNOWNs, 3 points each
4:	33 points

Consider the following program, input and output.
Find the UNKNOWNs:

Main {
  {{
  public static void main(String args[]) throws Exception {
    Input i = Input.parse(System.in);
    ClassGraph cg = new ClassGraph(true,false);
    ClassGraph cg2 = new ClassGraph(cg,
      "from Input bypassing -> *,tail,* to *");
    System.out.println(" output ");
    i.process(cg2);
    List l1 = i.gather1(cg2);
    List l2 = i.gather2(cg2);

    System.out.println(l1.equals(l2));
    System.out.println(" done" );
  }
  }}
}

Input {
{{
  void process(ClassGraph cg){
    cg.traverse(this, "from Input via Traversal to CdName", 
      new Visitor() {
	void before (CdName host){ 
	  System.out.println(host.get_ident()); }
      }
    );
  }
  List gather1(ClassGraph cg){
    List l1 = cg.gather(this, 
      "from Input via Traversal " + 
	  "via -> *,from1,* " + 
	  "via ClassName to edu.neu.ccs.demeter.Ident");
    l1.remove(0);
    System.out.println(l1.toString());
    System.out.println(" done gather 1 ");
    return(l1);
  }
  List gather2(ClassGraph cg){
    List l2 = cg.gather(this, 
      "from Input via Traversal " + 
	  "via -> *,to1,* " + 
	  "via ClassName to edu.neu.ccs.demeter.Ident");
    l2.remove(l2.size()-1);
    System.out.println(l2.toString());
    System.out.println(" done gather 2 ");
    return(l2);
  }
}}
}

input:

cds
(
  X 
    (
      A ( b B c C)
      B ( d D e E)
    )
  Y 
    (
      A ( b B c C)
      B ( d D e E)
    )
)
glue
(
  X.C = Y.C Y.E = Z.E Z.D = U.D
)
traversals
(
  t1 (
    in X from A to C
    in Y from C to E
    in Z from E to D
    in U from D to E
  )
)


output:

 output 
UNKNOWN1
UNKNOWN2
UNKNOWN3
UNKNOWN4
[UNKNOWN5, UNKNOWN6, UNKNOWN7]
 done gather 1 
[UNKNOWN8, UNKNOWN9, UNKNOWN10]
 done gather 2 
UNKNOWN11
 done


Question 5:
===========
2 UNKNOWNs, 10 points each.
5: 	20 points

Extend the class dictionary so that it accepts the following input:

//  same as before
...
traversals // this part is new
(
  t1 (
    in X from A via {X1,X2} bypassing {Y1} to C
    in Y from C via {X1,X2} bypassing {Y1} via {C} to E
    in Z from E bypassing {Y1} via {C} to D
    in U from D bypassing {Y1} via {X1} bypassing {Y1} to E
  )
)
Basically you can have any number of bypassing and via
constraints between "from" and "to".
Make your modification of the class dictionary
as simple as possible. Give the classes that you
modify and how you modify them
and write the new classes that are needed. 

Put your modified classes in UNKNOWN1.
Put your new classes in UNKNOWN2.