major(cs111).
major(cs230).
major(cs231).
major(cs235).
major(cs240).
major(cs251).
major(math225).

elective(cs204).
elective(cs220).
elective(cs232).
elective(cs234).
elective(cs242).

elective(cs301).
elective(cs304).
elective(cs305).
elective(cs307).
elective(cs313).
elective(cs315).
elective(cs320).
elective(cs321).
elective(cs322).
elective(cs332).
elective(cs341).
elective(cs342).
elective(cs343).

% programming, programming languages, programming systems, software tools
prog(cs111).
prog(cs230).
prog(cs251).

prog(cs204).
prog(cs301).
prog(cs304).

% theoretical foundations, formalism
theory(cs230).
theory(cs231).
theory(cs235).
theory(cs251).

theory(cs301).
theory(cs305).

% computer/computation implementation foundations, computer systems
systems(cs240).
systems(cs251).

systems(cs242).
systems(cs301).
systems(cs304).
systems(cs341).
systems(cs342).
systems(cs343).

% applications of computing
app(cs204).
app(cs232).
app(cs234).
app(cs305).
app(cs307).
app(cs313).
app(cs315).
app(cs320).
app(cs321).
app(cs322).

overlaps(X, Y) :- prog(X), prog(Y);
                  theory(X), theory(Y);
                  systems(X), systems(Y);
                  app(X), app(Y).
                    
complements(X, Y) :- theory(X), systems(Y);
                     systems(X), theory(Y);
                     app(X), systems(Y);
                     systems(X), app(Y);
                     theory(X), app(Y);
                     app(X), theory(Y);
                     prog(X), theory(Y);
                     theory(X), prog(Y);
                     prog(X), app(Y);
                     app(X), prog(Y);
                     prog(X), systems(Y);
                     systems(X), prog(Y).

% Another organization...
tag(cs111, prog).
tag(cs230, prog).
tag(cs204, prog).
tag(cs251, prog).
tag(cs301, prog).
tag(cs304, prog).

tag(cs230, theory).
tag(cs231, theory).
tag(cs235, theory).
tag(cs251, theory).
tag(cs301, theory).
tag(cs305, theory).

tag(cs240, systems).
tag(cs251, systems).
tag(cs242, systems).
tag(cs301, systems).
tag(cs304, systems).
tag(cs341, systems).
tag(cs342, systems).
tag(cs343, systems).

tag(cs204, app).
tag(cs232, app).
tag(cs234, app).
tag(cs305, app).
tag(cs307, app).
tag(cs313, app).
tag(cs315, app).
tag(cs320, app).
tag(cs321, app).
tag(cs322, app).

overlaps_tag(X, Y) :- tag(X, T), tag(Y, T).

% Using negation-as-failure. Return later for a deeper understanding of cut, negation.
% Effectively \+(Goal) :- Goal, !, fail.
complements_tag(X, Y) :- tag(X, TX), tag(Y, TY), \+ TX = TY.
% Careful with cut! It is not declarative. It side-effects the search directly. Order now matters.
% Avoid ! and \+ in the assignment.

% prereqs

prereq(cs111, cs230).
prereq(cs230, cs231).
prereq(cs230, cs235).
prereq(cs230, cs240).
prereq(cs230, cs251).
prereq(math225, cs231).
prereq(math225, cs235).

prereq(cs235, cs301).
prereq(cs240, cs301).
prereq(cs251, cs301).

prereq(cs230, cs242).
prereq(cs242, cs343).


prereqs_by_tag(X, Y, T) :- prereq(X, Y), tag(X, T), tag(Y, T).

core(C) :- major(C), prereq(cs230, C).

% This query is a good example to visualize unification and proof search.
% ?- trace.
% ?- prereqs_by_tag(cs230, C, theory).



% The assignment will ask you to define the equivalent of
% requires(Pre, Post) :- the course Pre must be taken before the course Post.
