You are on page 1of 3

_________________________ ____

Name Sec

Project 3 Questions
Instructions: Turn these answers in to the hw box. You must have these questions done by Project
3’s due date whether or not you have completed Project 3 on time. This will not be accepted late. We will
use a three point scale to grade every part of every question (e.g. 1a, 1b, 1c, and 1d). A 0 means either
that the answer is blank or that it isn’t even close. A 1 means it is minimally correct, but you could have
done better (we think you didn’t think it through very well.) A 2 means that it is satisfactory, but there is
room for improvement. A 3 means that it appears that you learned what you were supposed to learn and
you showed it to us. We hope and expect that you will get 3’s on each part. You get one point just for
turning it in for a total of 40 points.

Questions: Answers:
1. As you read the documentation you will
notice that for every class there is a domain
definition that is a logical or conceptual view
of the domain. Often the implementation
matches the conceptual point of view. For
instance, the conceptual definition for the
Token domain includes the three attributes:
type : TokenType
value : String
lineNumber : int
If you look at the source code you will see that
we implement the domain as:
protected TokenType type =

TokenType.UNDEFINED;
protected String value = null;
protected int lineNumber = -1;
At other times the domain definition is
significantly different from the
implementation. For instance, the domain
definition of Lex is:
tokens : Sequence<Token>
but the implementation is:
protected File file = null;
protected Token token = null;
In either case, we always include in a comment
the domain definition that matches the
conceptual view. Most students don’t include
a domain definition when they comment their
code. There is always a cost and a benefit to
providing domain definitions.
a) What is the cost?
b) What is the benefit?
c) Is the benefit worth the cost, why
don’t most students provide domain
definitions? If the benefit is not worth the
cost, explain why not.
2. The domain definition defines the data
structure of a class from an external point of
view. It defines what is wanted and imposes a
minimum set of constraints on the data
structure. By giving a definition, we can
determine if an implementation satisfies the
definition. For instance, the domain definition
of FactList is a set<Fact>. However, because
of inheritance, the domain is implemented as
ArrayList<Fact>. This could be a problem if
we allow the same fact to be added to
ArrayList twice.
a) In the code given, do we catch these
duplication errors?
b) Did we catch this during testing (look
at test/project3/FactListTest.java)?
c) Would you have even known there
was a problem without a domain
definition? (Why? Or why not?)
Two common solutions to this problem are to
(1) override the createList inherited from the
class List and make it check for duplicates, or
(2) change FactList so that it does not inherit
from DatalogSegment and implement the
domain as HashSet<Fact>.
d) Which would you choose and why?

3. Two techniques for increasing confidence in


the correctness of code are testing and code
reviews. There is a third technique employed
when the correctness of our code is extremely
critical. It is proof of correctness. The basic
structure of most proofs is to state what you are
going to prove (the conclusion), state the
premises, and then give the logic for arriving at
a conclusion. In the allConstants method of
the Head class in the project3 package there is
a pre-condition and a post-condition.
a) Which condition states the premises?
And which states the conclusion?
b) Outline a rough sketch of how you
would prove this method correct.
(Be sure to use induction if there is a
loop.)
4. Many define the semantics of a method M as
M.precondition ⇒ M.postcondition meaning that if
the pre-condition is true, then the execution of M
will guarantee that the post-condition is true. One
definition of what it means for method N to be a
specialization of M is N ⇒ M. This can be restated
as: (N.precondition ⇒ N.postcondition) ⇒
(M.precondition ⇒ M.postcondition)
Some have observed that if we are only allowed to
strengthen the post-condition (strengthening in our
case here means that N.postcondition ⇒
M.postcondition ) and are also only allowed to
weaken the precondition (weakening is the opposite
of strengthening and in this case here means
M.precondition ⇒ N.precondition ) then we can
guarantee that:
(N.precondition ⇒ N.postcondition) ⇒
(M.precondition ⇒ M.postcondition)
We can rewrite this claim as:
[(N.post ⇒ M.post) ∧ (M.pre ⇒ N.pre)] ⇒
[(N.pre ⇒ N.post) ⇒ (M.pre ⇒ M.post)]

a) Prove this claim by a Resolution proof.


You may abbreviate the variables as we did.

We can show that N.post ⇒ M.post is true if


M.post ∧ True ⇒ M.post. ( N.post = M.post ∧ T
because N is a specialized version of M ) Thus, to
strengthen the post-condition we “and” True to the
M’s post-condition. We can also show that M.pre
⇒ N.pre is true if M.pre ⇒ M.pre ∨ False. ( N.pre
= M.pre ∨ False ) Thus, to weaken the pre-
condition we “or” False to M’s pre-condition. The
method Query.initializeVariableInformation()
(abbreviate to init) is a specialization of
PredicateList.initializeVariableInformation().

b) How would you show this?


(Hint: post-conditions)

Query.keepOnGoing() (abbreviate to keep) is not a


specialization of PredicateList.keepOnGoing().

c) How would you show this?


(Hint: pre-conditions)

The method keepOnGoing() is an example of code


reuse but not method specialization.

d) Is this good or bad? Justify your answer.

You might also like