CSc 4340/6340, Introduction to Compilers
Spring 2012
PROJECT - Phase II

Phase I: (Due: 18 March, 2012 - Sunday)
Electronic submission under phase2

Implement the following semantic checks on the input query:

ANSWER PREDICATE CHECK

  1. Check if ANSWER predicate is present in head of rule
  2. Check if ANSWER predicate does not appear in rule body.

SAFETY CHECK

  1. All variables in head predicate also appear in regular body predicate; Anonymous variables are not allowed in head of rule
  2. All variables in NEGATED body predicate appear in POSITIVE regular body predicate; No Anonymous variables and Complex arguments in NEGATED body predicate

SCHEMA CHECK

  1. Check 1: Regular Body Predicate Check
  2. Check 2: Head Predicate Check
  3. Check 3: Complex Argument Check
  4. Check 4: Arity Check
  5. Check 5: Type Check

RECURSIVE QUERY CHECK

  1. No recursion allowed
  2. Construct stratification while doing this
  3. Construct hash map from predicate name to rules for the predicate (Use IDBPredicate class)

Here is a sample run on some input queries:

[raj@tinman phase2]$ java DLOG movies
type "help;" for usage...
Message: Database Provided: Database Directory is ./movies
DLOG> @q2;
----------INPUT QUERY----------------
APERSON(A) :- 
  ACTOR(T,A).
R(A,D) :- 
  ACTOR(T,A),
  DIRECTOR(T,D).
ANSWER(D) :- 
  ACTOR([*]:ACTOR(*,_),X).
------------------------------------
SEMANTIC ERROR: Head predicate contains variable not found in regular body predicate in Rule 3.
DLOG> @q3;
----------INPUT QUERY----------------
ANSWER(X,Y) :- 
  ACTOR(X,Y),
  not MOVIE(Y).
P(X,Y) :- 
  DIRECTOR(X,Y).
------------------------------------
NO SEMANTIC ERROR
DLOG> @q13;
----------INPUT QUERY----------------
APERSON(A) :- 
  ACTOR(T,A).
R(A,D) :- 
  ACTOR(T,A),
  DIRECTOR(T,D).
ANSWER(X) :- 
  ACTOR([*]:ACTOR(*,X),[*]:ACTOR(*,_)),
  APERSON(X).
------------------------------------
SEMANTIC ERROR: Complex Predicate cannot have variables - Rule 3
DLOG> x;
Exiting...
[raj@tinman phase2]

[raj@tinman phase2]$ java DLOG company
type "help;" for usage...
Message: Database Provided: Database Directory is ./company
DLOG> @q1;
----------INPUT QUERY----------------
TEMP2(X,Y) :- 
  WORKS_ON(X,Y,_).
ANSWER(F,M,L) :- 
  EMPLOYEE(F,M,L,S,_,_,_,_,_,5),
  WORKS_ON(S,P,H),
  TEMP2(X,Y,Z),
  ANSWER('ProductX',P,_,_),
  H >= 10.
------------------------------------
SEMANTIC ERROR: ANSWER predicate should not appear in rule body.
DLOG> @q4;
----------INPUT QUERY----------------
TEMP1(S,P) :- 
  EMPLOYEE(_,_,_,S,_,_,_,_,_,_),
  PROJECTS(_,P,_,_).
TEMP2(S,P) :- 
  WORKS_ON(S,P,_).
TEMP3(S) :- 
  TEMP1(S,P),
  not TEMP2(S,P).
ANSWER(F,M,L) :- 
  EMPLOYEE(F,M,L,S,_,_,_,_,_,_),
  not TEMP3(S).
------------------------------------
NO SEMANTIC ERROR
DLOG> @q5;
----------INPUT QUERY----------------
TEMP1(S,P) :- 
  EMPLOYEE(_,_,_,S,_,_,_,_,_,_),
  PROJECTS(_,P,_,_).
TEMP2(S,P) :- 
  WORKS_ON(S,P,_).
TEMP3(S) :- 
  TEMP1(S,P),
  not TEMP2(S,P).
ANSWER(F,M,L) :- 
  EMPLOYEE(F,M,L,S,_,_,_,_,_,_),
  not TEMP3(S).
------------------------------------
NO SEMANTIC ERROR
DLOG> @q6;
----------INPUT QUERY----------------
ANSWER(X) :- 
  TEMP(X).
------------------------------------
SEMANTIC ERROR: Predicate TEMP not present in head of query rule or in database.
DLOG> @q7;
----------INPUT QUERY----------------
TEMP1(S) :- 
  WORKS_ON(S,P,_),
  PROJECTS(_,P,'Houston',_).
TEMP2(S) :- 
  EMPLOYEE(_,_,_,S,_,_,_,_,_,D),
  not DEPT_LOCATIONS(D,'Houston').
ANSWER(F,M,L,A) :- 
  EMPLOYEE(F,M,L,S,_,A,_,_,_,_),
  TEMP1(S).
ANSWER(F,M,L,A) :- 
  EMPLOYEE(F,M,L,S,_,A,_,_,_,_),
  TEMP2(S).
------------------------------------
NO SEMANTIC ERROR
DLOG> @q8;
----------INPUT QUERY----------------
ANSWER(X,Y) :- 
  WORKS_ON(X,Y,Y).
------------------------------------
NO SEMANTIC ERROR
DLOG> @q9;
----------INPUT QUERY----------------
TEMP1(S) :- 
  WORKS_ON(S,P,_),
  PROJECTS(_,P,'Houston',_).
TEMP2(S) :- 
  EMPLOYEE(_,_,_,S,_,_,_,_,_,D),
  not DEPT_LOCATIONS(D,'Houston').
ANSWER(F,M,L,A) :- 
  EMPLOYEE(F,M,L,S,_,A,_,_,_,_),
  TEMP1(S).
ANSWER(F,M,L,A) :- 
  EMPLOYEE(F,M,L,S,_,A,_,'1',_,_),
  TEMP2(S).
------------------------------------
SEMANTIC ERROR: Data Type Mismatch in Body Predicate EMPLOYEE: Found 1 in place of NUMBER
DLOG> @q10;
----------INPUT QUERY----------------
ANSWER(X,Z) :- 
  WORKS_ON(X,Y,_),
  Z = 10.
------------------------------------
NO SEMANTIC ERROR
DLOG> @q11;
----------INPUT QUERY----------------
ANSWER(X,Z) :- 
  WORKS_ON(X,Y,U),
  Z = 1.
------------------------------------
NO SEMANTIC ERROR
DLOG> @q12;
----------INPUT QUERY----------------
ANSWER(X,V) :- 
  WORKS_ON(X,Y,U),
  Z = 10.
------------------------------------
SEMANTIC ERROR: Head predicate contains variable not found in regular body predicate in Rule 1.
DLOG> exit;
Exiting...
[raj@tinman phase2]$

[raj@tinman phase2]$ java DLOG erf
type "help;" for usage...
Message: Database Provided: Database Directory is ./erf
DLOG> @q15;
----------INPUT QUERY----------------
ANSWER(X,Y) :- 
  R(X,Y,[*,*]:F(_,*,*),_).
------------------------------------
SEMANTIC ERROR: Data Type of */# in Complex Predicate F does not match type in parent predicate: Found STRING in place of NUMBER
DLOG> exit;
Exiting...
[raj@tinman phase2]

The program should also build a data structure to capture the essential information in a query. Here is my design of the data structure:

public class Program {
  private Vector<Rule> rules;
  // Phase 2 Variables
  private HashMap<String,IDBPredicate> idbPredicateData;
  private Vector<String> idbPredicateNamesOrderedByStrata;
}

public class Rule {
  private Predicate headPredicate;
  private Vector<Predicate> bodyPredicates;
  // Phase 2 Variables
  private Vector<Predicate> regularBodyPredicates;
  private Vector<Predicate> comparisonBodyPredicates;
}

public class Predicate {
  private String predName;
  private Vector<Argument> arguments;
  private boolean isNegated;
  private boolean isComparison;
  private Argument leftOperand;
  private String comparisonOperator;
  private Argument rightOperand;
}

public class Argument {
  private boolean isConstant = false; // true if constant argument
  private boolean isUnderscore = false; // true if _ argument
  private String argDataType; // data type for argument : "NUMBER" or "STRING"
  private String argName; // name of argument - if variable or if "*" or "#"
  private String argValue; // value of argument in case of constant argument
  private boolean isComplex; // true for complex arguments
  private Predicate complexPredicate; // stores predicate after : in complex argument; may be null
  private int numberOfStarsOrHashes; // Store the number of stars or hashes in complex argument
}

The following will replace the above class for Datalog (to be used by undergraduates):

public class Argument {
  private boolean isConstant = false; // true if constant argument
  private boolean isUnderscore = false; // true if _ argument
  private String argDataType; // data type for argument : "NUMBER" or "STRING"
  private String argName; // name of argument if variable
  private String argValue; // value of argument in case of constant argument
}

// Phase 2 Class
// comparison is done on stratum value
public class IDBPredicate implements Comparable {
  String predicateName;
  Vector<Rule> rules;
  Vector<String> argDataType;
  int stratum;
}