1% Computational Intelligence: a logical approach.
    2% CILOG Code. Section 3.6.
    3% Copyright (c) 1998, Poole, Mackworth, Goebel and Oxford University Press
    4
    5% The following example shows how we can combine databases and
    6% sophisticated rules in order to represent non-trivial regulations
    7% of a university. This is intended to show a knowledge-based
    8% application of our definite clause language.
    9
   10% This assumes that we have databases about individual students and about
   11% what grades they achieved in different courses.
   12
   13% grade(St,Course,Mark) is true if student St achieved Mark in Course.
   14grade(robin,engl101,87).
   15grade(robin,phys101,89).
   16grade(robin,chem101,67).
   17grade(robin,math101,77).
   18grade(robin,cs126,84).
   19grade(robin,cs202,88).
   20grade(robin,geol101,74).
   21grade(robin,phys202,92).
   22grade(robin,math202,81).
   23grade(robin,cs204,87).
   24grade(robin,hist101,66).
   25grade(robin,cs333,77).
   26grade(robin,cs312,74).
   27grade(robin,math302,41).
   28grade(robin,math302,87).
   29grade(robin,cs304,79).
   30grade(robin,cs804,80).
   31grade(robin,psyc303,85).
   32grade(robin,stats324,91).
   33grade(robin,cs405,77).
   34
   35% We also have database relations about the structure of the university,
   36% and information about different courses.
   37% dept(Dept,Fac) is true if department Dept is in faculty Fac
   38dept(history,arts).
   39dept(english,arts).
   40dept(psychology,science).
   41dept(statistics,science).
   42dept(mathematics,science).
   43dept(cs,science).
   44
   45% course(Course,Dept,Level) is true if Course is a course in department Dept,
   46% at level Level.
   47course(hist101,history,first).
   48course(engl101,english,first).
   49course(psyc303,psychology,third).
   50course(stats324,statistics,third).
   51course(math302,mathematics,third).
   52course(phys101,physics,first).
   53
   54% We can use rules to represent what is needed for degree requirements. Here
   55% we give the subset of the degree requirements for a fictional university that
   56% are applicable for computer science students.
   57% These will be used to illustrate the power of our representation.
   58
   59% completed_degree(St,Dept) is true if student St has completed a four-year 
   60% degree in department Dept. In order to have satisfied these requirements,
   61% the student must have covered the core courses of the department, satisfied
   62% the faculty requirements of the faculty in which the department is, they
   63% must have fulfilled the electives requirement, and must have enough units.
   64satisfied_degree_requirements(St,Dept) <-
   65   covers_core_courses(St,Dept) &
   66   dept(Dept,Fac) &
   67   satisfies_faculty_req(Fac,St) &
   68   fulfilled_electives(St,Dept) &
   69   enough_units(St,Dept).
   70
   71% covers_core_courses(St,Dept) is true if student St has covered the core 
   72% courses for department Dept.
   73covers_core_courses(St,Dept) <-
   74   core_courses(Dept,CC,MinPass) &
   75   passed_each(CC,St,MinPass).
   76
   77% core_courses(Dept,CC,MinPass) is true if CC is the list of core courses
   78% for department Dept, and MinPass is the passing grade for these core courses.
   79
   80% The core courses for a cs degree are cs202, math202, cs204, cs304 and math302
   81% The student must pass each with at least 65% to pass
   82core_courses(cs,[cs202,math202,cs204,cs304,math302],65).
   83
   84% passed_each(CL,St,MinPass) is true if student St has a grade of at least
   85% MinPass in each course in the courses in list CL of courses.
   86passed_each([],_,_).
   87passed_each([C|R],St,MinPass) <-
   88   passed(St,C,MinPass) &
   89   passed_each(R,St,MinPass).
   90
   91% passed(St,C,MinPass) is true if student St has a grade of at least
   92% MinPass in course C
   93passed(St,C,MinPass) <-
   94   grade(St,C,Gr) &
   95   Gr >= MinPass.
   96
   97% The faculty requirements for the science faculty are that a student must 
   98% have passed (i.e., have greater than 50%)
   99% in engl101, phys101, chem101, math101, either cs101 or stats101 and
  100% either biol101, geol101 or astr101.
  101satisfies_faculty_req(science,St) <-
  102   passed_each([engl101,phys101,chem101,math101],St,50) &
  103   passed_one([cs126,stats101],St,50) &
  104   passed_one([bil101,geol101,astr101],St,50).
  105
  106% passed_one(CL,St,MinPass) is true if student St has a grade of at least
  107% MinPass in one of the courses in the courses in list CL of courses.
  108passed_one(CL,St,MinPass) <-
  109   member(C,CL) &
  110   passed(St,C,MinPass).
  111
  112
  113% fulfilled_electives(St,Dept) is student St has fulfilled the elective 
  114% requirements for department Dept.
  115% A student in a science department needs an arts course 
  116% (other than engl101) &
  117% and two science courses from departments other than their own.
  118% The science courses have to be third or fourth year courses.
  119fulfilled_electives(St,SciDept) <-
  120   dept(SciDept,science) &
  121   has_arts_elective(St) &
  122   has_sci_elective(St,SciDept,Sci1) &
  123   has_sci_elective(St,SciDept,Sci2) &
  124   Sci1 \= Sci2.
  125
  126% has_arts_elective(St) is true if student St has passed an arts course 
  127% (other than engl101)
  128has_arts_elective(St) <-
  129   passed(St,ArtsEl,50) &
  130   course(ArtsEl,ArtsDept,_) &
  131   dept(ArtsDept,arts) &
  132   ArtsEl \= engl101.
  133
  134% has_sci_elective(St,Major,SciC) is true if SciC is a third or fourth year 
  135% course passed by student 
  136% St. SciC must be in a science department other than department Major.
  137has_sci_elective(St,Major,SciC) <-
  138   passed(St,SciC,50) &
  139   course(SciC,Dept,Level) &
  140   Dept \= Major &
  141   dept(Dept,science) &
  142   member(Level,[third,fourth]).
  143
  144% enough_units(St,Dept) is true if student St has enough units for a degree
  145% in department Dept.
  146enough_units(St,SciDept) <-
  147   dept(SciDept,science) &
  148   has_courses(St,_,18,50).
  149
  150% has_courses(St,L,N,MinPass) is true if L is a list of N courses that student 
  151% St has passed with a grade of at least MinPass.
  152has_courses(_,[],0,_).
  153has_courses(St,[C|R],N1,MinPass) <-
  154   N is N1-1 &
  155   has_courses(St,R,N,MinPass) &
  156   passed(St,C,MinPass) &
  157   notin(C,R).
  158
  159% member(X,L) is true if X is an element of list L
  160member(X,[X|_]).
  161member(X,[_|R]) <-
  162   member(X,R).
  163
  164% notin(X,L) is true if X is not an element of list L
  165notin(_,[]).
  166notin(A,[H|T]) <-
  167   A \= H &
  168   notin(A,T).
  169
  170% EXAMPLE QUERIES
  171% ask satisfied_degree_requirements(robin,cs).
  172% ask has_courses(robin,L,19,50).
  173% ask has_courses(robin,L,20,50).  %WARNING: THIS TAKES A *VERY* LONG TIME
  174
  175% EXERCISES
  176% Fix up our knowledge base so that a student cannot count
  177% core courses as electives. 
  178% Explain why the inequality is needed at the end of the definition of
  179% fulfilled_electives. 
  180% Explain why enough_units constructs a list of the courses taken. What is
  181% the major efficiency problem with this procedure? How can this be fixed?