diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..9c52276 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6eefc39 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Created by pytest automatically. +venv/ +venv-python3.10/ +studyreg_programs/ +/clinguin diff --git a/README.md b/README.md index a32af75..fe63a87 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,26 @@ -# study-reg-clinguin -Clinguin UI for Study regulations +# Running Clinguin Program +## Prerequisites -### Usage +- Python 3.10 -#### cogsys.lp: -``` -clinguin client-server --domain-files new/instance/cogsys.lp new/encoding.lp --ui-files new/ui.lp -c n=4 -``` -#### cscbsc.lp: -``` -clinguin client-server --domain-files new/instance/cscbsc.lp new/encoding.lp --ui-files new/ui.lp -c n=4 -``` -#### cscmsc.lp: -``` -clinguin client-server --domain-files new/instance/cscmsc.lp new/encoding.lp --ui-files new/ui.lp -c n=4 -``` -#### dsmsc.lp: -``` -clinguin client-server --domain-files new/instance/dsmsc.lp new/encoding.lp --ui-files new/ui.lp -c n=4 -``` -#### irsba.lp: -``` -clinguin client-server --domain-files new/instance/irsba.lp new/encoding.lp --ui-files new/ui.lp -c n=4 -``` +## Instructions +1. **Clone the repository and navigate to the project directory:** + ```bash + git clone https://github.com/krr-up/study-reg-clinguin.git + cd study-reg-clinguin + ``` -### Clinguin version -`Clinguin 1.0.16` \ No newline at end of file +2. **Install the required dependencies:** + ```bash + pip install -r requirements.txt + ``` + +3. **Run the Clinguin server:** + ```bash + clinguin client-server --domain-files instances/cogsys.lp encodings/meta.lp encodings/cogsys_info.lp encodings/preference.lp --ui-files ui/ui_main.lp -c n=3 + ``` + +### Clinguin Version + +`Clinguin 2.0.0` diff --git a/TODOS.md b/TODOS.md deleted file mode 100644 index e69de29..0000000 diff --git a/encodings/.DS_Store b/encodings/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/encodings/.DS_Store differ diff --git a/encodings/cogsys_info.lp b/encodings/cogsys_info.lp new file mode 100644 index 0000000..a0930c3 --- /dev/null +++ b/encodings/cogsys_info.lp @@ -0,0 +1,103 @@ +% This instance models the structure of the study program "Cognitive Systems: Language, Learning and Reasoning (COG)". +% It defines the program, the modules offered, and the corresponding examinations for each module. + +% The `program/4` predicate defines the overall study program, consisting of: +% - The program abbreviation (e.g., "COG"). +% - The full title of the program (e.g., "Cognitive Systems: Language, Learning and Reasoning"). +% - The degree offered (e.g., "MS" for Master of Science). +% - The version of the program (e.g., "20142"). + +% The `module_program/5` predicate defines the modules within the program, consisting of: +% - A module ID (e.g., "55580"). +% - The full title of the module (e.g., "Machine Learning and Data Analysis"). +% - The module abbreviation (e.g., "bm2"). +% - The number of credits for the module (e.g., "9"). +% - The program the module belongs to (e.g., "COG"). + +% The `examination/6` predicate defines the examination tasks for each module, consisting of: +% - An exam ID (e.g., "555802"). +% - The form of the examination (e.g., "MP" for oral examination). +% - The title of the examination (e.g., "Mündliche Prüfung"). +% - The examination type (e.g., "PL" for graded exams, "SL" for ungraded performance or ). +% - The module the exam is part of (e.g., "bm2"). +% - The study program it is part of (e.g., "COG"). + +% Degrees: +% - B2: Zwei-Fach-Bachelor (Two-subject Bachelor) +% - BA: Bachelor of Arts +% - BL: Bachelor of Education +% - ML: Master of Education +% - MT: Master of Arts + +% Examination types: +% - PL: primary examination +% - PNL: secondary examination +% - SL: Studienleistung (an ungraded academic achievement that is not required for module completion, with no prerequisite checks) + +% Examination forms: +% MP: Mündliche Prüfung (Oral Exam) +% V: Vorlesung (Lecture) +% U: Übung (Exercise) +% PR: Praktisches Arbeiten (Practical Work) +% PJ: Projekt (Project) +% V1: Vorlesung oder Seminar (Lecture or Seminar) +% S: Seminar (Seminar) + + +program("COG","Cognitive Systems: Language, Learning and Reasoning","MS","20142"). +module_program("55580","Machine Learning and Data Analysis",bm2,9,"COG"). +examination(ep_bm2__208555,"MP","Mündliche Prüfung","PL",bm2,"COG"). +examination(es_bm2__218555,"V","Intelligent Data Analysis","SL",bm2,"COG"). +examination(es_bm2__318555,"U","Intelligent Data Analysis","PNL",bm2,"COG"). +module_program("55590","Advanced Problem Solving Techniques",bm3,9,"COG"). +examination(ep_bm3__109555,"MP","Klausur","PL",bm3,"COG"). +examination(es_bm3__119555,"V","Vorlesung","SL",bm3,"COG"). +examination(es_bm3__219555,"U","Übung","SL",bm3,"COG"). +examination(es_bm3__319555,"PR","Praktisches Arbeiten","PNL",bm3,"COG"). +examination(es_bm3__419555,"PJ","Projekt","PNL",bm3,"COG"). +module_program("55600","Foundations of Computer Science",fm2,6,"COG"). +examination(ep_fm2__100655,"MP","Mündliche Prüfung","PL",fm2,"COG"). +examination(es_fm2__110655,"V","Video-Vorlesung","SL",fm2,"COG"). +examination(es_fm2__210655,"U","Übung","PNL",fm2,"COG"). +module_program("55610","Current Topics in Computational Intelligence 1",am31,6,"COG"). +examination(ep_am31__111655,"V1","Vorlesung oder Seminar","PL",am31,"COG"). +module_program("55620","Current Topics in Computational Intelligence 2",am32,6,"COG"). +examination(ep_am32__112655,"V1","Vorlesung oder Seminar","PL",am32,"COG"). +module_program("55630","Project in Computational Intelligence",pm3,12,"COG"). +examination(es_pm3__113655,"S","Seminar","PL",pm3,"COG"). +module_program("82190","Advanced Natural Language Processing",bm1,9,"COG"). +examination(ep_bm1__109128,"MP","Klausur","PL",bm1,"COG"). +examination(ep_bm1__209128,"MP","Abschlussprojekt","PL",bm1,"COG"). +examination(es_bm1__119128,"V","Vorlesung","SL",bm1,"COG"). +examination(es_bm1__219128,"U","Übung","PNL",bm1,"COG"). +module_program("82200","Foundations of Mathematics",fm1,6,"COG"). +examination(ep_fm1__100228,"MP","Mündliche Prüfung","PL",fm1,"COG"). +examination(es_fm1__110228,"V","Video-Vorlesung","SL",fm1,"COG"). +examination(es_fm1__210228,"U","Übung","PNL",fm1,"COG"). +module_program("82210","Foundations of Linguistics",fm3,6,"COG"). +examination(ep_fm3__101228,"MP","Mündliche Prüfung","PL",fm3,"COG"). +examination(es_fm3__111228,"V","Video-Vorlesung","SL",fm3,"COG"). +examination(es_fm3__211228,"U","Übung","PNL",fm3,"COG"). +module_program("82220","Current Topics in Computational Linguistics 1",am11,6,"COG"). +examination(ep_am11__112228,"V1","Vorlesung oder Seminar","PL",am11,"COG"). +module_program("82230","Current Topics in Computational Linguistics 2",am12,6,"COG"). +examination(ep_am12__113228,"V1","Vorlesung oder Seminar","PL",am12,"COG"). +module_program("82240","Current Topics in Machine Learning 1",am21,6,"COG"). +examination(ep_am21__114228,"V1","Vorlesung oder Seminar","PL",am21,"COG"). +module_program("82250","Current Topics in Machine Learning 2",am22,6,"COG"). +examination(ep_am22__115228,"V1","Vorlesung oder Seminar","PL",am22,"COG"). +module_program("82260","Project in Computational Linguistics",pm1,12,"COG"). +examination(es_pm1__116228,"S","Seminar","PL",pm1,"COG"). +module_program("82270","Project in Machine Learning",pm2,12,"COG"). +examination(es_pm2__117228,"S","Seminar","PL",pm2,"COG"). +module_program("82280","Individual Research Module",im,15,"COG"). +examination(ep_im__118228,"PJ","Forschungsprojekt","PL",im,"COG"). +module_program("","Master's Thesis",msc,30,"COG"). +examination(ep_msc,"","Master's Thesis","PL",msc,"COG"). +examination(es_msc,"","Master's Thesis","PL",msc,"COG"). + +% Custom module sets +set_name(m,"All Modules",4). +set_name(p, "Project Seminars",2). +set_name(o, "Elective Modules",3). +set_name(b, "Mandatory Modules",1). \ No newline at end of file diff --git a/encodings/encoding-examinations.lp b/encodings/encoding-examinations.lp new file mode 100644 index 0000000..7bf0499 --- /dev/null +++ b/encodings/encoding-examinations.lp @@ -0,0 +1,184 @@ +% examinations input: +% * in(X,ep) +% * in(X,es) +% * map(ep,M,X) +% * map(es,M,X) +% * in((X,Y),d) + +% generate +{ in(E,e(I)) } :- X=(ep;es), in(E,X), I=1..n. + +% ee = e(1) U ... U e(n) +in(E,ee) :- in(E,e(I)). + +% before(I) = e(1) U ... U e(I) +in(E,before(I)) :- I=1..n, in(E,e(J)), J<=I. + +% function f from e(I)'s to s(I)'s +in(M,s(I)) :- in(M,m), I=1..n, + map(ep,M,P), in(X,P), + map(es,M,S), in(Y,S), + in(E,before(I)) : in(E,X); + in(E,before(I)) : in(E,Y); + 1 { not in(E,before(I-1)) : in(E,X) ; + not in(E,before(I-1)) : in(E,Y) }. + +% s = s(1) U ... U s(n) +in(E,s) :- in(E,s(I)). + +% m(w) and m(s) +in(E,m(X)) :- X = (s;w), in(E,m), map(s,E,X). + +% constraints (logical connectives) +constraint( if(X,Y)) :- if(X,Y). +constraint( eq(X,Y)) :- eq(X,Y). +constraint(and(X,Y)) :- and(X,Y). +constraint( or(X,Y)) :- or(X,Y). +constraint( neg(X)) :- neg(X). +constraint(exists(A,B,X)) :- exists(A,B,X). % exists some A from B such that X +% % A has to be a unique name occurring in X and nowhere else + +% constraints (relations) +constraint( empty(A)) :- empty(A). +constraint(nonempty(A)) :- nonempty(A). +% +constraint( subset(A,B)) :- subset(A,B). +constraint(subseteq(A,B)) :- subseteq(A,B). +constraint( equal(A,B)) :- equal(A,B). +constraint(supseteq(A,B)) :- supseteq(A,B). +constraint( supset(A,B)) :- supset(A,B). +constraint( in'(A,B)) :- in'(A,B). % the set A belongs to the set of sets B +% +constraint( card(A,R,L)) :- card(A,R,L). +constraint(sum(A,M,R,L)) :- sum(A,M,R,L). +% +constraint(notafter(A,B)) :- notafter(A,B). % in the e(I)'s no element of A occurs after some element of B + +% statements +st(X) :- constraint(X). +st(X) :- st( if(X,Y)). st(Y) :- st( if(X,Y)). +st(X) :- st( eq(X,Y)). st(Y) :- st( eq(X,Y)). +st(X) :- st(and(X,Y)). st(Y) :- st(and(X,Y)). +st(X) :- st( or(X,Y)). st(Y) :- st( or(X,Y)). +st(X) :- st( neg(X)). +st(X) :- st(exists(A,B,X)). + +% additional sets (logical connectives) +set(B) :- st(exists(A,B,X)). + +% additional sets (relations) +set(A) :- st( empty(A)). +set(A) :- st(nonempty(A)). +% +set(A) :- st( subset(A,B)). set(B) :- st( subset(A,B)). +set(A) :- st(subseteq(A,B)). set(B) :- st(subseteq(A,B)). +set(A) :- st( equal(A,B)). set(B) :- st( equal(A,B)). +set(A) :- st(supseteq(A,B)). set(B) :- st(supseteq(A,B)). +set(A) :- st( supset(A,B)). set(B) :- st( supset(A,B)). +set(A) :- st( in'(A,B)). set(B) :- st( in'(A,B)). +% +set(A) :- st( card(A,R,X)). +set(A) :- st( sum(A,M,R,X)). +% +set(A) :- st(notafter(A,B)). set(B) :- st(notafter(A,B)). + +% additional sets (set operations) +set(A) :- set(int(A,B)). set(B) :- set(int(A,B)). +in(E,int(A,B)) :- set(int(A,B)), in(E,A), in(E,B). +% +set(A) :- set(union(A,B)). set(B) :- set(union(A,B)). +in(E,union(A,B)) :- set(union(A,B)), in(E,A). +in(E,union(A,B)) :- set(union(A,B)), in(E,B). +% +set(A) :- set(expand(A)). +in(F,expand(A)) :- set(expand(A)), in(E,A), in(F,E). +% +set(A) :- set(before(A)). % contains the elements that occur in s(I) before some element of A +in(E,before(A)) :- set(before(A)), in(E,s(I)), in(F,A), in(F,s(J)), I < J. +% +set(A) :- set(after(A)). % contains the elements that occur in s(I) after some element of A +in(E,after(A)) :- set(after(A)), in(E,s(I)), in(F,A), in(F,s(J)), I > J. +% +set(A) :- set(between(A)). % contains the elements that occur in s(I) between some elements of A +in(E,between(A)) :- set(between(A)), in(E,s(I)), in(F,A), in(F,s(J)), + in(G,A), in(G,s(K)), F != G, J <= I, I <= K. + + +% holds (logical connectives) +holds( if(X,Y)) :- st( if(X,Y)), not holds(X). +holds( if(X,Y)) :- st( if(X,Y)), holds(Y). +holds( eq(X,Y)) :- st( eq(X,Y)), holds(X), holds(Y). +holds( eq(X,Y)) :- st( eq(X,Y)), not holds(X), not holds(Y). +holds(and(X,Y)) :- st(and(X,Y)), holds(X), holds(Y). +holds( or(X,Y)) :- st( or(X,Y)), holds(X). +holds( or(X,Y)) :- st( or(X,Y)), holds(Y). +holds( neg(X)) :- st( neg(X)), not holds(X). +% +{ assign(A,E) : in(E,B) } = 1 :- st(exists(A,B,X)). + in(F,A) :- st(exists(A,B,X)), assign(A,E), in(F,E). + holds(exists(A,B,X)) :- st(exists(A,B,X)), holds(X). + +% holds (relations) +holds( empty(A)) :- st( empty(A)), not in(_,A). +holds(nonempty(A)) :- st(nonempty(A)), in(_,A). +% +holds( subset(A,B)) :- st( subset(A,B)), not in(E,A), in(E,B), in(F,B) : in(F,A). +holds(subseteq(A,B)) :- st(subseteq(A,B)), in(E,B) : in(E,A). +holds( equal(A,B)) :- st( equal(A,B)), in(E,A) : in(E,B); in(E,B) : in(E,A). +holds(supseteq(A,B)) :- st(supseteq(A,B)), in(E,A) : in(E,B). +holds( supset(A,B)) :- st( supset(A,B)), in(E,A), not in(E,B), in(F,A) : in(F,B). +holds( in'(A,B)) :- st( in'(A,B)), in(E,B), in(F,A) : in(F,E); in(F,E) : in(F,A). +% +holds(card(A, lt,X)) :- st(card(A, lt,X)), { in(E,A) } < X. +holds(card(A,leq,X)) :- st(card(A,leq,X)), { in(E,A) } <= X. +holds(card(A, eq,X)) :- st(card(A, eq,X)), { in(E,A) } = X. +holds(card(A,geq,X)) :- st(card(A,geq,X)), { in(E,A) } >= X. +holds(card(A, gt,X)) :- st(card(A, gt,X)), { in(E,A) } > X. +holds(card(A, bw,(L,U))) :- st(card(A, bw,(L,U))), L { in(E,A) } U. +% +holds(sum(A,M, lt,X)) :- st(sum(A,M, lt,X)), #sum{ V,E : in(E,A), map(M,E,V) } < X. +holds(sum(A,M,leq,X)) :- st(sum(A,M,leq,X)), #sum{ V,E : in(E,A), map(M,E,V) } <= X. +holds(sum(A,M, eq,X)) :- st(sum(A,M, eq,X)), #sum{ V,E : in(E,A), map(M,E,V) } = X. +holds(sum(A,M,geq,X)) :- st(sum(A,M,geq,X)), #sum{ V,E : in(E,A), map(M,E,V) } >= X. +holds(sum(A,M, gt,X)) :- st(sum(A,M, gt,X)), #sum{ V,E : in(E,A), map(M,E,V) } > X. +holds(sum(A,M, bw,(L,U))) :- st(sum(A,M,bw,(L,U))), L #sum{ V,E : in(E,A), map(M,E,V) } U. +% +holds(notafter(A,B)) :- st(notafter(A,B)), I <= J : in(E,A), in(E,e(I)), in(F,B), in(F,e(J)). + +% it cannot be the case that a constraint does not hold +:- constraint(X), not holds(X). +% +% for debugging: +% error(X) :- constraint(X), not holds(X). +% #minimize{ 1,X: error(X) }. +% #show error/1. + +% display +%#show. +%#show (E,e(I)) : in(E,e(I)). +%#show (E,s(I)) : in(E,s(I)). +%#show in/2. +%#show _any_opt/1. + +% defined +#defined if/2. +#defined eq/2. +#defined and/2. +#defined or/2. +#defined neg/1. +#defined exists/3. +% +#defined empty/1. +#defined nonempty/1. +% +#defined subset/2. +#defined subseteq/2. +#defined equal/2. +#defined supseteq/2. +#defined supset/2. +#defined in'/2. +% +#defined card/3. +#defined sum/4. +% +#defined notafter/2. \ No newline at end of file diff --git a/encodings/meta-examinations.lp b/encodings/meta-examinations.lp new file mode 100644 index 0000000..233742b --- /dev/null +++ b/encodings/meta-examinations.lp @@ -0,0 +1,182 @@ +% examinations input: +% * in(X,ep) +% * in(X,es) +% * map(ep,M,X) +% * map(es,M,X) +% * in((X,Y),d) + +% generate +{ in(E,e(I)) } :- X=(ep;es), in(E,X), I=1..n. + +% ee = e(1) U ... U e(n) +in(E,ee) :- in(E,e(I)). + +% before(I) = e(1) U ... U e(I) +in(E,before(I)) :- I=1..n, in(E,e(J)), J<=I. + +% function f from e(I)'s to s(I)'s +in(M,s(I)) :- in(M,m), I=1..n, + map(ep,M,P), in(X,P), + map(es,M,S), in(Y,S), + in(E,before(I)) : in(E,X); + in(E,before(I)) : in(E,Y); + 1 { not in(E,before(I-1)) : in(E,X) ; + not in(E,before(I-1)) : in(E,Y) }. + +% s = s(1) U ... U s(n) +in(E,s) :- in(E,s(I)). + +% m(w) and m(s) +in(E,m(X)) :- X = (s;w), in(E,m), map(s,E,X). + +% constraints (logical connectives) +constraint( if(X,Y)) :- if(X,Y). +constraint( eq(X,Y)) :- eq(X,Y). +constraint(and(X,Y)) :- and(X,Y). +constraint( or(X,Y)) :- or(X,Y). +constraint( neg(X)) :- neg(X). +constraint(exists(A,B,X)) :- exists(A,B,X). % exists some A from B such that X +% % A has to be a unique name occurring in X and nowhere else + +% constraints (relations) +constraint( empty(A)) :- empty(A). +constraint(nonempty(A)) :- nonempty(A). +% +constraint( subset(A,B)) :- subset(A,B). +constraint(subseteq(A,B)) :- subseteq(A,B). +constraint( equal(A,B)) :- equal(A,B). +constraint(supseteq(A,B)) :- supseteq(A,B). +constraint( supset(A,B)) :- supset(A,B). +constraint( in'(A,B)) :- in'(A,B). % the set A belongs to the set of sets B +% +constraint( card(A,R,L)) :- card(A,R,L). +constraint(sum(A,M,R,L)) :- sum(A,M,R,L). +% +constraint(notafter(A,B)) :- notafter(A,B). % in the e(I)'s no element of A occurs after some element of B + +% statements +st(X) :- constraint(X). +st(X) :- st( if(X,Y)). st(Y) :- st( if(X,Y)). +st(X) :- st( eq(X,Y)). st(Y) :- st( eq(X,Y)). +st(X) :- st(and(X,Y)). st(Y) :- st(and(X,Y)). +st(X) :- st( or(X,Y)). st(Y) :- st( or(X,Y)). +st(X) :- st( neg(X)). +st(X) :- st(exists(A,B,X)). + +% additional sets (logical connectives) +set(B) :- st(exists(A,B,X)). + +% additional sets (relations) +set(A) :- st( empty(A)). +set(A) :- st(nonempty(A)). +% +set(A) :- st( subset(A,B)). set(B) :- st( subset(A,B)). +set(A) :- st(subseteq(A,B)). set(B) :- st(subseteq(A,B)). +set(A) :- st( equal(A,B)). set(B) :- st( equal(A,B)). +set(A) :- st(supseteq(A,B)). set(B) :- st(supseteq(A,B)). +set(A) :- st( supset(A,B)). set(B) :- st( supset(A,B)). +set(A) :- st( in'(A,B)). set(B) :- st( in'(A,B)). +% +set(A) :- st( card(A,R,X)). +set(A) :- st( sum(A,M,R,X)). +% +set(A) :- st(notafter(A,B)). set(B) :- st(notafter(A,B)). + +% additional sets (set operations) +set(A) :- set(int(A,B)). set(B) :- set(int(A,B)). +in(E,int(A,B)) :- set(int(A,B)), in(E,A), in(E,B). +% +set(A) :- set(union(A,B)). set(B) :- set(union(A,B)). +in(E,union(A,B)) :- set(union(A,B)), in(E,A). +in(E,union(A,B)) :- set(union(A,B)), in(E,B). +% +set(A) :- set(expand(A)). +in(F,expand(A)) :- set(expand(A)), in(E,A), in(F,E). +% +set(A) :- set(before(A)). % contains the elements that occur in s(I) before some element of A +in(E,before(A)) :- set(before(A)), in(E,s(I)), in(F,A), in(F,s(J)), I < J. +% +set(A) :- set(after(A)). % contains the elements that occur in s(I) after some element of A +in(E,after(A)) :- set(after(A)), in(E,s(I)), in(F,A), in(F,s(J)), I > J. +% +set(A) :- set(between(A)). % contains the elements that occur in s(I) between some elements of A +in(E,between(A)) :- set(between(A)), in(E,s(I)), in(F,A), in(F,s(J)), + in(G,A), in(G,s(K)), F != G, J <= I, I <= K. + + +% holds (logical connectives) +holds( if(X,Y)) :- st( if(X,Y)), not holds(X). +holds( if(X,Y)) :- st( if(X,Y)), holds(Y). +holds( eq(X,Y)) :- st( eq(X,Y)), holds(X), holds(Y). +holds( eq(X,Y)) :- st( eq(X,Y)), not holds(X), not holds(Y). +holds(and(X,Y)) :- st(and(X,Y)), holds(X), holds(Y). +holds( or(X,Y)) :- st( or(X,Y)), holds(X). +holds( or(X,Y)) :- st( or(X,Y)), holds(Y). +holds( neg(X)) :- st( neg(X)), not holds(X). +% +{ assign(A,E) : in(E,B) } = 1 :- st(exists(A,B,X)). + in(F,A) :- st(exists(A,B,X)), assign(A,E), in(F,E). + holds(exists(A,B,X)) :- st(exists(A,B,X)), holds(X). + +% holds (relations) +holds( empty(A)) :- st( empty(A)), not in(_,A). +holds(nonempty(A)) :- st(nonempty(A)), in(_,A). +% +holds( subset(A,B)) :- st( subset(A,B)), not in(E,A), in(E,B), in(F,B) : in(F,A). +holds(subseteq(A,B)) :- st(subseteq(A,B)), in(E,B) : in(E,A). +holds( equal(A,B)) :- st( equal(A,B)), in(E,A) : in(E,B); in(E,B) : in(E,A). +holds(supseteq(A,B)) :- st(supseteq(A,B)), in(E,A) : in(E,B). +holds( supset(A,B)) :- st( supset(A,B)), in(E,A), not in(E,B), in(F,A) : in(F,B). +holds( in'(A,B)) :- st( in'(A,B)), in(E,B), in(F,A) : in(F,E); in(F,E) : in(F,A). +% +holds(card(A, lt,X)) :- st(card(A, lt,X)), { in(E,A) } < X. +holds(card(A,leq,X)) :- st(card(A,leq,X)), { in(E,A) } <= X. +holds(card(A, eq,X)) :- st(card(A, eq,X)), { in(E,A) } = X. +holds(card(A,geq,X)) :- st(card(A,geq,X)), { in(E,A) } >= X. +holds(card(A, gt,X)) :- st(card(A, gt,X)), { in(E,A) } > X. +holds(card(A, bw,(L,U))) :- st(card(A, bw,(L,U))), L { in(E,A) } U. +% +holds(sum(A,M, lt,X)) :- st(sum(A,M, lt,X)), #sum{ V,E : in(E,A), map(M,E,V) } < X. +holds(sum(A,M,leq,X)) :- st(sum(A,M,leq,X)), #sum{ V,E : in(E,A), map(M,E,V) } <= X. +holds(sum(A,M, eq,X)) :- st(sum(A,M, eq,X)), #sum{ V,E : in(E,A), map(M,E,V) } = X. +holds(sum(A,M,geq,X)) :- st(sum(A,M,geq,X)), #sum{ V,E : in(E,A), map(M,E,V) } >= X. +holds(sum(A,M, gt,X)) :- st(sum(A,M, gt,X)), #sum{ V,E : in(E,A), map(M,E,V) } > X. +holds(sum(A,M, bw,(L,U))) :- st(sum(A,M,bw,(L,U))), L #sum{ V,E : in(E,A), map(M,E,V) } U. +% +holds(notafter(A,B)) :- st(notafter(A,B)), I <= J : in(E,A), in(E,e(I)), in(F,B), in(F,e(J)). + +% it cannot be the case that a constraint does not hold +:- constraint(X), not holds(X). +% +% for debugging: +% error(X) :- constraint(X), not holds(X). +% #minimize{ 1,X: error(X) }. +% #show error/1. + +% display +%#show. +%#show (E,e(I)) : in(E,e(I)). +%#show (E,s(I)) : in(E,s(I)). + +% defined +#defined if/2. +#defined eq/2. +#defined and/2. +#defined or/2. +#defined neg/1. +#defined exists/3. +% +#defined empty/1. +#defined nonempty/1. +% +#defined subset/2. +#defined subseteq/2. +#defined equal/2. +#defined supseteq/2. +#defined supset/2. +#defined in'/2. +% +#defined card/3. +#defined sum/4. +% +#defined notafter/2. diff --git a/old/encoding.lp b/encodings/meta.lp similarity index 94% rename from old/encoding.lp rename to encodings/meta.lp index ea2ada7..fc90e87 100644 --- a/old/encoding.lp +++ b/encodings/meta.lp @@ -33,5 +33,5 @@ in(E1,before(A)) :- set(before(A)), in(E1,s(I)), in(E2,A), in(E2,s(J)), I < J. :- sum(A,F,geq, L), not L #sum{ V,E : in(E,A), map(F,E,V) }. % display -% #show. -% #show (M,I) : in(M,s(I)). +%#show. +%#show (M,I) : in(M,s(I)). diff --git a/encodings/preference.lp b/encodings/preference.lp new file mode 100644 index 0000000..425fd5c --- /dev/null +++ b/encodings/preference.lp @@ -0,0 +1,26 @@ +use_preferences. +% Define modules based on 'in' predicate from cogsys.lp +module(E) :- in(E, m). + +% Define preference options +preference(include(hard), "Include"). +preference(exclude(hard), "Exclude"). +preference(include(soft), "Try to include"). +preference(exclude(soft), "Try to exclude"). + +% External predicates to set preferences for modules +#external user_preference(P, E) : module(E), preference(P,_). [false] + +% Hard constraint: Required modules must be included +:- user_preference(include(hard), E), not in(E, s(_)). +:- user_preference(exclude(hard), E), in(E, s(_)). +:~ user_preference(include(soft), E), not in(E, s(_)).[1@1,E] +:~ user_preference(exclude(soft), E), in(E, s(_)).[1@1,E] +%:- not in(am11, s(1)). + +% Test preferences for example +% user_preference(include, am11). +% user_preference(exclude, am12). +%* preference(excluded, fm1). +preference(preferred, am11). +preference(not_preferred, pm1). *% diff --git a/encodings/ui_extra.lp b/encodings/ui_extra.lp new file mode 100644 index 0000000..b7d59b1 --- /dev/null +++ b/encodings/ui_extra.lp @@ -0,0 +1,364 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Semester Definition and Configuration +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Define the range of semesters based on the constant 'n' +semester(I) :- _clinguin_const(n,N), I = 1..N. + +% Define possible values for the number of semesters +values(3..8). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Root Window Configuration +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Define the root window element and set its layout to column +elem(root_window, window, root). +attr(root_window, flex_direction, column). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Main Layout Container +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Main container holding the left, center, and right sections +elem(main_container, container, root_window). +attr(main_container, class, ("d-flex"; "flex-column"; "flex-lg-row"; "justify-content-between"; "align-items-start"; "m-2")). +attr(main_container, child_layout, flex). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Left Section Configuration +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Left container holding the module selection options +elem(left_section, container, main_container). +attr(left_section, order, 1). +attr(left_section, class, ("col-12"; "col-md-12"; "col-lg-2"; "p-3"; "mb-lg-0"; "mr-lg-auto")). +attr(left_section, child_layout, flex). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Container for Selected Modules + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Container for displaying selected modules with checkboxes + elem(selected_modules_container, container, left_section). + attr(selected_modules_container, class, ("border-opacity-50"; "fw-bold"; "p-2"; "m-2"; "rounded"; "border"; "border-secondary"; "border-2")). + attr(selected_modules_container, flex_direction, column). + attr(selected_modules_container, order, 2). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Label for Module Selection + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Label container for the module selection section + elem(module_selection_label_container, container, selected_modules_container). + attr(module_selection_label_container, order, 1). + attr(module_selection_label_container, class, ("bg-secondary"; "text-light"; "fw-bold"; "p-2"; "mt-2"; "mb-2"; "rounded")). + + % Label text for the module selection section + elem(module_selection_label, label, module_selection_label_container). + attr(module_selection_label, label, "Select Preferred Modules:"). + attr(module_selection_label, order, 1). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Display of Modules with Checkboxes + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Container for displaying modules as checkboxes + elem(modules_checkbox_container, container, selected_modules_container). + attr(modules_checkbox_container, order, 2). + attr(modules_checkbox_container, class, ("d-flex"; "flex-wrap"; "pt-2")). + attr(modules_checkbox_container, flex_direction, row). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Update Module Checkbox Logic + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Display each module as a checkbox with a label + elem(module_checkbox(E), checkbox, modules_checkbox_container) :- in(E, _). + attr(module_checkbox(E), checked, true) :- in(E, _), not ignored(E). + attr(module_checkbox(E), label, E) :- in(E, _). + attr(module_checkbox(E), class, ("text-capitalize"; "h6"; "m-2"; "text-secondary")) :- in(E, _). + + % Disable the checkbox if the atom is in all solutions + attr(module_checkbox(E), disabled, true) :- _all(in(E,s)). + + % Update the 'ignored' atom when a checkbox is clicked, but only if it's not mandatory + when(module_checkbox(E), click, call, remove_atom(ignored(E))) :- + in(E, _), ignored(E), not mandatory_module(E). + when(module_checkbox(E), click, call, (add_atom(ignored(E)), remove_assumption_signature(in(E, any)))) :- + in(E, _), not ignored(E), not mandatory_module(E). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Center Section Configuration +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Center container holding the semester display and controls +elem(center_section, container, main_container). +attr(center_section, order, 2). +attr(center_section, class, ("col-12"; "col-md-12"; "col-lg-8"; "pt-3"; "mb-3"; "mb-lg-0"; "d-flex"; "justify-content-center")). +attr(center_section, child_layout, flex). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Container for Semester Count and Update Control + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Container for displaying the current number of semesters and providing an update option + elem(semester_control_container, container, center_section). + attr(semester_control_container, order, 4). + attr(semester_control_container, flex_direction, column). + attr(semester_control_container, class, ("m-2")). + attr(semester_control_container, class, "align-self-center"). + + % Label displaying the current number of semesters + elem(semester_count_label, label, semester_control_container). + attr(semester_count_label, label, @concat("Current number of semesters: ", N)) :- _clinguin_const(n, N). + attr(semester_count_label, order, 1). + attr(semester_count_label, class, ("fw-bold"; "p-2"; "m-2")). + + % Dropdown menu for selecting the number of semesters + elem(semester_dropdown, dropdown_menu, semester_control_container). + attr(semester_dropdown, order, 2). + attr(semester_dropdown, selected, "Change"). + attr(semester_dropdown, class, ("btn-sm"; "btn-secondary"; "p-2"; "m-2")). + + % Dropdown menu items representing possible semester values + elem(semester_option(V), dropdown_menu_item, semester_dropdown) :- values(V). + attr(semester_option(V), label, V) :- values(V). + when(semester_option(V), click, call, set_constant("n", V)) :- values(V). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Container for Semester Display + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Container for displaying the list of semesters + elem(semester_display_container, container, center_section). + attr(semester_display_container, order, 2). + attr(semester_display_container, class, ("d-flex"; "flex-wrap"; "flex-row"; "justify-content-center"; "align-items-start"; "w-100")). + + % Individual semester containers within the semester display + elem(semester_container(I), container, semester_display_container) :- semester(I). + attr(semester_container(I), order, I) :- semester(I). + attr(semester_container(I), class, ("border-opacity-50"; "fw-bold"; "p-3"; "m-2"; "rounded"; "border"; "border-secondary"; "border-2"; "bg-light")) :- semester(I). + + % Header for each semester container + elem(semester_header_container(I), container, semester_container(I)) :- semester(I). + attr(semester_header_container(I), order, 1) :- semester(I). + attr(semester_header_container(I), class, ("bg-secondary";"text-light";"fw-bold";"p-2";"m-1"; "rounded")) :- semester(I). + + % Label for each semester header + elem(semester_label(I), label, semester_header_container(I)) :- semester(I). + attr(semester_label(I), label, @concat("Semester ",I)) :- semester(I). + attr(semester_label(I), order, 1) :- semester(I). + + % Dropdown menu for assigning modules to a semester + elem(assign_module_dropdown(I), dropdown_menu, semester_header_container(I)) :- semester(I). + attr(assign_module_dropdown(I), order, 2) :- semester(I). + attr(assign_module_dropdown(I), selected, "Assign module") :- semester(I). + attr(assign_module_dropdown(I), class, ("btn-sm";"btn-outline-light"; "m-2")) :- semester(I). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Dropdown Menu Items for Module Assignment + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Include only modules that are not ignored in the dropdown menu + elem(assign_module_option(I,E), dropdown_menu_item, assign_module_dropdown(I)) :- _any(in(E,s(I))), not _all(in(E,s(I))), not ignored(E). + attr(assign_module_option(I,E), label, @concat(E, " (", C, " ECTS)")) :- _any(in(E,s(I))), not _all(in(E,s(I))), map(c, E, C). + when(assign_module_option(I,E), click, call, add_assumption(in(E,s(I)))) :- _any(in(E,s(I))), not _all(in(E,s(I))). + + % Container for modules within each semester + elem(semester_modules_container(I), container, semester_container(I)) :- semester(I). + attr(semester_modules_container(I), class, ("bg-wight")) :- semester(I). + attr(semester_modules_container(I), order, 2) :- semester(I). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Module Display within Semesters + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Define when a module should be shown within a semester + shown_module(E,I) :- _all(in(E,s(I))), not ignored(E). + shown_module(E,I) :- in(E,s(I)), _clinguin_browsing, not ignored(E). + + % Container for each module displayed within a semester + elem(displayed_module(I,E), container, semester_modules_container(I)) :- shown_module(E,I). + attr(displayed_module(I,E), height, C*10) :- shown_module(E,I), map(c,E,C). + attr(displayed_module(I,E), class, ("border"; "border-secondary"; + "d-flex";"flex-row";"justify-content-between";"align-items-center"; + "p-3";"m-2"; "rounded"; "border-2"; "border-opacity-50"; "bg-white")) :- shown_module(E,I). + + % Label for each displayed module + elem(module_label(I,E), label, displayed_module(I,E)) :- shown_module(E,I). + attr(module_label(I,E), label, E) :- shown_module(E,I). + attr(module_label(I,E), class, ("text-black"; "fw-bold")) :- shown_module(E,I). + + % Button for removing a module from a semester + elem(remove_module_button(I,E), button, displayed_module(I,E)) :- _clinguin_assume(in(E,s(I)), true). + attr(remove_module_button(I,E), icon, "fa-times") :- _clinguin_assume(in(E,s(I)), true). + attr(remove_module_button(I,E), class, ("btn-sm";"btn-outline")) :- _clinguin_assume(in(E,s(I)), true). + when(remove_module_button(I,E), click, call, remove_assumption(in(E,s(I)))) :- _clinguin_assume(in(E,s(I)), true). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Display of Total Credits for Each Semester + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Container for displaying total credits under each semester + elem(semester_credits_container(I), container, semester_container(I)) :- semester(I). + attr(semester_credits_container(I), order, 3) :- semester(I). + attr(semester_credits_container(I), class, ("bg-light"; "p-2"; "mt-2"; "rounded"; "text-center"; "fw-bold"; "mt-auto")) :- semester(I). + + % Label for displaying total credits under each semester + elem(semester_credits_label(I), label, semester_credits_container(I)) :- semester(I). + attr(semester_credits_label(I), label, @concat(SC, " ECTS")) :- + semester(I), + SC = #sum{ C,E : map(c,E,C), shown_module(E,I) }. + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Display of Total Credits at the Top of the Page + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Container for displaying the total credits across all semesters + elem(total_credits_display_container, container, center_section). + attr(total_credits_display_container, order, 1). + attr(total_credits_display_container, class, ("bg-secondary"; "text-white"; "p-3"; "rounded"; "m-2"; "align-self-center")). + + % Label for displaying the total credits + elem(total_credits_label, label, total_credits_display_container). + attr(total_credits_label, label, @concat("Total credits: ", TC)) :- + TC = #sum{ C,E : map(c,E,C), shown_module(E,_) }. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Right Section Configuration +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Right container holding the subset modules and progress bars +elem(right_section, container, main_container). +attr(right_section, order, 3). +attr(right_section, class, ("col-12"; "col-md-12"; "col-lg-2"; "ml-lg-auto"; "mb-lg-0"; "p-3"; "d-flex"; "flex-row"; "flex-wrap"; "flex-lg-column")). +attr(right_section, child_layout, flex). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Containers for Module Subsets + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Identify all subsets of modules + subset(E,S) :- map(l, S, _); map(u, S, _), in(E, S). + + % Create containers for each subset of modules + elem(subset_container(S), container, right_section) :- subset(E,S). + attr(subset_container(S), class, ("border-opacity-50";"fw-bold";"p-2";"rounded"; "border"; "border-secondary"; "border-2"; "col-12"; "col-sm-12"; "col-md-12"; "d-flex"; "flex-column")) :- subset(E,S). + attr(subset_container(S), flex_direction, column) :- subset(E,S). + attr(subset_container(S), order, 2) :- subset(E,S). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Labels for Module Subsets + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Label container for each subset of modules + elem(subset_label_container(S), container, subset_container(S)):-subset(E,S). + attr(subset_label_container(S), order, 1):-subset(E,S). + attr(subset_label_container(S), class, ("bg-secondary";"text-light";"fw-bold";"p-2";"mt-2";"mb-2";"rounded")):-subset(E,S). + + % Label text for each subset + elem(subset_label(S), label, subset_label_container(S)):-subset(E,S). + attr(subset_label(S), label, @concat("Modules ", S)):-subset(E,S), S != m. + attr(subset_label(S), label, "All Modules"):-subset(E,m), S == m. + attr(subset_label(S), order, 1):-subset(E,S). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Display Modules in Subsets + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Container for displaying modules within each subset + elem(subset_modules_container(S), container, subset_container(S)) :- subset(E,S). + attr(subset_modules_container(S), order, 2):- subset(E,S). + attr(subset_modules_container(S), class, ("d-flex"; "flex-wrap"; "pt-2")):- subset(E,S). + attr(subset_modules_container(S), flex_direction, row) :- subset(E,S). + + % Module is visibly selected if it is shown in any semester + module_visibly_selected(E) :- shown_module(E, I), semester(I). + + % Button for each module in a subset + elem(subset_module_button(E,S), button, subset_modules_container(S)) :- in(E,S), subset(E,S). + attr(subset_module_button(E,S), label, E) :- in(E,S), subset(E,S). + attr(subset_module_button(E,S), class, ("btn-sm"; "m-1"; "disabled")) :- in(E,S), subset(E,S). + attr(subset_module_button(E,S), class, "btn-secondary") :- in(E,S), subset(E,S), module_visibly_selected(E). + attr(subset_module_button(E,S), class, "btn-outline-secondary") :- in(E,S), subset(E,S), not module_visibly_selected(E). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Display Progress Bars for Credits in Each Subset + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Calculate the total credits for visibly selected modules within each subset + subset_total_credits(S, TotalCredits) :- + subset(_, S), + TotalCredits = #sum { C, E : module_visibly_selected(E), in(E, S), map(c, E, C) }. + + % Calculate the remaining credits required for each subset + remaining_credits(S, Remaining, TotalCredits) :- + map(l, S, LowerBound), + subset_total_credits(S, TotalCredits), + Remaining = LowerBound - TotalCredits. + + % Calculate the percentage of credits completed for each subset + progress_percentage(S, Percentage) :- + map(l, S, LowerBound), + subset_total_credits(S, TotalCredits), + LowerBound > 0, + Percentage = (TotalCredits * 100) / LowerBound. + + % Container for the progress bar showing percentage of completed credits + elem(progress_bar_container(S), container, subset_container(S)) :- subset(_, S). + attr(progress_bar_container(S), order, 4) :- subset(_, S). + attr(progress_bar_container(S), class, ("m-1"; "pt-3"; "mt-auto")) :- subset(_, S). + + % Progress bar indicating the percentage of credits completed + elem(subset_progress_bar(S), progress_bar, progress_bar_container(S)) :- subset(_, S). + attr(subset_progress_bar(S), value, P) :- progress_percentage(S, P). + attr(subset_progress_bar(S), class, ("progress-bar-striped"; "progress-bar-animated"; "rounded")) :- subset(_, S). + attr(subset_progress_bar(S), out_label, @concat(Remaining, " ECTS")) :- + remaining_credits(S, Remaining, _), Remaining > 0. + attr(subset_progress_bar(S), label, @concat(TotalCredits, " ECTS")) :- + remaining_credits(S, _, TotalCredits). + attr(subset_progress_bar(S), height, 30) :- progress_percentage(S, P). + attr(subset_progress_bar(S), class, "bg-success") :- progress_percentage(S, P), P >= 100. + attr(subset_progress_bar(S), class, "bg-warning") :- progress_percentage(S, P), P >= 50, P < 100. + attr(subset_progress_bar(S), class, "bg-danger") :- progress_percentage(S, P), P < 50. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Main Menu Bar Configuration +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Configuration for the main menu bar at the top of the window +elem(menu_bar, menu_bar, root_window). +attr(menu_bar, title, "Study Regulations"). +attr(menu_bar, icon, "fa-graduation-cap"). + +% Button to clear all assumptions +elem(menu_bar_clear, button, menu_bar). +attr(menu_bar_clear, label, "Clear"). +attr(menu_bar_clear, icon, "fa-trash"). +attr(menu_bar_clear, class, ("btn-sm"; "btn-outline-secondary")). +when(menu_bar_clear, click, call, clear_assumptions). + +% Button to move to the next solution +elem(menu_bar_next, button, menu_bar). +attr(menu_bar_next, label, "Next"). +attr(menu_bar_next, icon, "fa-forward-step"). +attr(menu_bar_next, class, ("btn-sm"; "btn-outline-secondary")). +when(menu_bar_next, click, call, next_solution). + +% Button to select the current solution +elem(menu_bar_select, button, menu_bar). +attr(menu_bar_select, label, "Select"). +attr(menu_bar_select, icon, "fa-hand-pointer"). +attr(menu_bar_select, class, ("btn-sm"; "btn-outline-secondary")). +when(menu_bar_select, click, call, select). + +% Button to download the ASP model +elem(menu_bar_download_asp, button, menu_bar). +attr(menu_bar_download_asp, label, "Download ASP Model"). +attr(menu_bar_download_asp, icon, "fa-download"). +attr(menu_bar_download_asp, class, ("btn-sm"; "btn-outline-secondary")). +when(menu_bar_download_asp, click, call, download("#show in.", "asp_study_plan.lp")). + +% Add borders to all containers (for debugging): +% attr(E,class,("border-1";"border";"border-dark")):- elem(E, container, _). diff --git a/instances/cogsys-examinations.lp b/instances/cogsys-examinations.lp new file mode 100644 index 0000000..f3eccfd --- /dev/null +++ b/instances/cogsys-examinations.lp @@ -0,0 +1,31 @@ +% +% in(X,ep) +% in(X,es) +% map(ep,M,X) +% map(es,M,X) +% in((X,Y),d) +% + +% ... + +% regular constraints +if( + nonempty(int(ee,expand(union(A,B)))), + in'(int(ee,expand(A)),A) +) :- in(M,m), map(ep,M,A), map(es,M,B). +% +if( + neg(empty(int(ee,expand(union(A,B))))), + in'(int(ee,expand(B)),B) +) :- in(M,m), map(ep,M,A), map(es,M,B). + +% temporal constraints +empty(int(e(I),e(J))) :- I = 1..n, J = 1..n, I < J. +% +if( + subseteq(X,ee), + exists(sk(X,Y),Y,and( + subseteq(sk(X,Y),ee), + notafter(sk(X,Y),X) + )) +) :- in((X,Y),d). \ No newline at end of file diff --git a/old/instance.lp b/instances/cogsys.lp similarity index 80% rename from old/instance.lp rename to instances/cogsys.lp index 2f44220..4a6254f 100644 --- a/old/instance.lp +++ b/instances/cogsys.lp @@ -1,4 +1,4 @@ -#const n = 4. +%#const n = 4. % b, f, a, o and p % c in((bm1;bm2;bm3),b). map(c,(bm1;bm2;bm3),9). @@ -14,11 +14,11 @@ in(E,m) :- in(E,(b;f;a;p)). map(s,bm1,w;s,bm2,s;s,bm3,w). in((im;msc),m). map(s,(fm1;fm2;fm3),w). map(s,(am11;am12;am21),e). map(s,(am22;am31;am32),e). -% e map(s,(pm1;pm2;pm3),e). -in(fm1,e). map(s,(im1;msc1),e). + map(s,(pm1;pm2;pm3),e). + map(s,(im;msc),e). - % l and u - map(l,b,27;l,o,24;l,p,24;l,m,120). +% e % l and u +in(fm1,e). map(l,b,27;l,o,24;l,p,24;l,m,120). map(u,b,27;u,o,24;u,p,24;u,m,120). % global constraints @@ -30,5 +30,4 @@ in(im,gc3). in(msc,gc3). subseteq(gc3,s). empty(int(s(I),s(J))) :- I = 1..n, J = 1..n, I < J. empty(int(m(w),s(2*K ))) :- K = 1..n, 1 <= 2*K, 2*K <= n. empty(int(m(s),s(2*K-1))) :- K = 1..n, 1 <= 2*K-1, 2*K-1 <= n. -in(msc,tc4). sum(before(tc4),c,geq,90). - +in(msc,tc4). sum(before(tc4),c,geq,90). \ No newline at end of file diff --git a/instances/test-cogsys-exams.lp b/instances/test-cogsys-exams.lp new file mode 100644 index 0000000..3c45c16 --- /dev/null +++ b/instances/test-cogsys-exams.lp @@ -0,0 +1,198 @@ +% +% * in(X,ep) +% * in(X,es) +% * map(ep,M,X) +% * map(es,M,X) +% * in((X,Y),d) +% +% '%\*' means "madeup - no such data on PULS" + +%bm1 +map(ep,bm1,ep_bm1). +in(ep_bm1_01,ep_bm1). +in((ep_bm1__109128;ep_bm1__209128),ep_bm1_01). + +map(es,bm1,es_bm1). +in(es_bm1_01,es_bm1). +in((es_bm1__119128;es_bm1__219128),es_bm1_01). + + +%bm2 +map(ep,bm2,ep_bm2). +in(ep_bm2_01,ep_bm2). +in(ep_bm2__208555,ep_bm2_01). + +map(es,bm2,es_bm2). +in(es_bm2_01,es_bm2). +in((es_bm2__218555;es_bm2__318555),es_bm2_01). + + +%bm3 +map(ep,bm3,ep_bm3). +in(ep_bm3_01,ep_bm3). +in(ep_bm3__109555,ep_bm3_01). + +map(es,bm3,es_bm3). +in(es_bm3_01,es_bm3). +in((es_bm3__119555;es_bm3__219555;es_bm3__319555;es_bm3__419555),es_bm3_01). + + +%pm1 +map(ep,pm1,ep_pm1). +in(ep_pm1_01,ep_pm1). +in(ep_pm1__116228,ep_pm1_01). %\* + +map(es,pm1,es_pm1). +in(es_pm1_01,es_pm1). +in(es_pm1__116228,es_pm1_01). + + +%pm2 +map(ep,pm2,ep_pm2). +in(ep_pm2_01,ep_pm2). +in(ep_pm2__117228,ep_pm2_01). %\* + +map(es,pm2,es_pm2). +in(es_pm2_01,es_pm2). +in(es_pm2__117228,es_pm2_01). + + +%pm3 +map(ep,pm3,ep_pm3). +in(ep_pm3_01,ep_pm3). +in(ep_pm3__113655,ep_pm3_01). %\* + +map(es,pm3,es_pm3). +in(es_pm3_01,es_pm3). +in(es_pm3__113655,es_pm3_01). + + +%am11 +map(ep,am11,ep_am11). +in(ep_am11_01,ep_am11). +in(ep_am11__112228,ep_am11_01). %\* + +map(es,am11,es_am11). +in(es_am11_01,es_am11). +in(es_am11__112228,es_am11_01). + + +%am12 +map(ep,am12,ep_am12). +in(ep_am12_01,ep_am12). +in(ep_am12__113228,ep_am12_01). %\* + +map(es,am12,es_am12). +in(es_am12_01,es_am12). +in(es_am12__113228,es_am12_01). + + + +%am21 +map(ep,am21,ep_am21). +in(ep_am21_01,ep_am21). +in(ep_am21__114228,ep_am21_01). %\* + +map(es,am21,es_am21). +in(es_am21_01,es_am21). +in(es_am21__114228,es_am21_01). + +%am22 +map(ep,am22,ep_am22). +in(ep_am22_01,ep_am22). +in(ep_am22__115228,ep_am22_01). %\* + +map(es,am22,es_am22). +in(es_am22_01,es_am22). +in(es_am22__115228,es_am22_01). + +%am31 +map(ep,am31,ep_am31). +in(ep_am31_01,ep_am31). +in(ep_am31__111655,ep_am31_01). %\* + +map(es,am31,es_am31). +in(es_am31_01,es_am31). +in(es_am31__111655,es_am31_01). + +%am32 +map(ep,am32,ep_am32). +in(ep_am32_01,ep_am32). +in(ep_am32__112655,ep_am32_01). %\* + +map(es,am32,es_am32). +in(es_am32_01,es_am32). +in(es_am32__112655,es_am32_01). + +%fm1 +map(ep,fm1,ep_fm1). +in(ep_fm1_01,ep_fm1). +in(ep_fm1__100228,ep_fm1_01). %\* + +map(es,fm1,es_fm1). +in(es_fm1_01,es_fm1). +in((es_fm1__110228;es_fm1__210228),es_fm1_01). + +%fm2 +map(ep,fm2,ep_fm2). +in(ep_fm2_01,ep_fm2). +in(ep_fm2__100655,ep_fm2_01). + +map(es,fm2,es_fm2). +in(es_fm2_01,es_fm2). +in((es_fm2__110655;es_fm2__210655),es_fm2_01). + +%fm3 +map(ep,fm3,ep_fm3). +in(ep_fm3_01,ep_fm3). +in(ep_fm3__010228,ep_fm3_01). + +map(es,fm3,es_fm3). +in(es_fm3_01,es_fm3). +in((es_fm3__111228;es_fm3__211228),es_fm3_01). + +%im +map(ep,im,ep_im). +in(ep_im_01,ep_im). +in(ep_im__118228,ep_im_01). %\* +%- +map(es,im,es_im). +in(es_im_01,es_im). +in(es_im__118228,es_im_01). + +%msc +map(ep,msc,ep_msc). +in(ep_msc_01,ep_msc). +in(ep_msc,ep_msc_01). %\* + +map(es,msc,es_msc). +in(es_msc_01,es_msc). +in(es_msc,es_msc_01). %\* + +%Ep and Es +in(F,ep) :- map(ep,_,X), in(E,X), in(F,E). +in(F,es) :- map(es,_,X), in(E,X), in(F,E). + + +%d +%bm1 +in(es_bm1_01,d_bm1). +in((ep_bm1_01,d_bm1),d). + +%bm2 +in(es_bm2_01,d_bm2). +in((ep_bm2_01,d_bm2),d). + + +% constraint - the primary and secondary examination tasks for each module must be in the same semester +:- in(Ep,e(I)), not in(Es,e(I)), + in(Ep,W), in(W,R), + map(es,M,R), + in(Es,W'), in(W',R'), + map(ep,M,R'). + +:- not in(Ep,e(I)), in(Es,e(I)), + in(Ep,W), in(W,R), + map(es,M,R), + in(Es,W'), in(W',R'), + map(ep,M,R'). diff --git a/new/README.md b/new/README.md deleted file mode 100644 index 1c5a4c6..0000000 --- a/new/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Meta Program - - - -Run: - -``` -clinguin client-server --domain-files new/instance/'instance.lp' new/encoding.lp --ui-files new/ui.lp -c n=4 -``` -- `instance.lp`: any instance in the instance folder, and -- `n`: number of semesters for the study planning. - - - diff --git a/new/commonconstraints.lp b/new/commonconstraints.lp deleted file mode 100644 index d657798..0000000 --- a/new/commonconstraints.lp +++ /dev/null @@ -1,5 +0,0 @@ - - -empty(int(s(I),s(J))) :- I = 1..n, J = 1..n, I < J. -empty(int(m(w),s(2*K ))) :- K = 1..n, 1 <= 2*K, 2*K <= n. -empty(int(m(s),s(2*K-1))) :- K = 1..n, 1 <= 2*K-1, 2*K-1 <= n. \ No newline at end of file diff --git a/new/defined.lp b/new/defined.lp deleted file mode 100644 index d366200..0000000 --- a/new/defined.lp +++ /dev/null @@ -1,10 +0,0 @@ - -#defined subseteq/2. -#defined equal/2. -#defined card/3. -#defined d/2. -#defined b/2. -#defined focus/0. -#defined focusset/1. -#defined focusescardinality/2. -#defined card/4. \ No newline at end of file diff --git a/new/encoding.lp b/new/encoding.lp deleted file mode 100644 index 59920f2..0000000 --- a/new/encoding.lp +++ /dev/null @@ -1,54 +0,0 @@ -%% Ground work by Javier %% - -#include "defined.lp". -#include "commonconstraints.lp". - -% generate -{ in(E,s(I)) } :- in(E,m), I=1..n. - -% s = s(1) U ... U s(n) -in(E,s) :- in(E,s(I)). - -% m(w) and m(s) -in(E,m(Z)) :- Z = (s;w), in(E,m), map(s,E,Z). - -% additional sets -set(A) :- empty(A). -set(A) :- subseteq(A,B). set(A) :- equal(A,B). -set(B) :- subseteq(A,B). set(B) :- equal(A,B). -set(A) :- card(A,R,L). set(A) :- sum(A,M,R,L). -% -set(A) :- set( int(A,B)). set(B) :- set(int(A,B)). -set(A) :- set(before(A)). -% -in( E, int(A,B)) :- set( int(A,B)), in(E,A), in(E,B). -in(E1,before(A)) :- set(before(A)), in(E1,s(I)), in(E2,A), in(E2,s(J)), I < J. - -% constraints -:- empty(A), in(E,A). -% -:- subseteq(A,B), in(E,A), not in(E,B). -% -:- equal(A,B), in(E,A), not in(E,B). -:- equal(A,B), not in(E,A), in(E,B). -% -:- card(A,bw,(L,U)), not L { in(E,A) } U. -:- card(A,leq, U), not { in(E,A) } U. -% dependency constraint -:- d(M,M'), in(M,s(J)), in(M',s(I)), J >= I. -% "blocking modules" constraint -:- b(M,M'), in(M,s), in(M',s). -%* :- b(M,M'), - #count{M: in(M,s); M': in(M',s)} > 1. *% -% -:- sum(A,F,bw,(L,U)), not L #sum{ V,E : in(E,A), map(F,E,V) } U. -:- sum(A,F,geq, L), not L #sum{ V,E : in(E,A), map(F,E,V) }. - -% for optimization -%:~ recommend(M,M'), in(M,s), not in(M',s), pref_id = p1.[1,M,M'] -%:~ recommend(M,M'), in(M',s), in(M,s), pref_id = p3.[1,M,M'] - - -% display - #show. - #show (M,I) : in(M,s(I)). \ No newline at end of file diff --git a/new/instance/cogsys _with_rec.lp b/new/instance/cogsys _with_rec.lp deleted file mode 100755 index 41803f1..0000000 --- a/new/instance/cogsys _with_rec.lp +++ /dev/null @@ -1,103 +0,0 @@ -% b, f, a, o and p % c -in((bm1;bm2;bm3),b). map(c,(bm1;bm2;bm3),9). -in((fm1;fm2;fm3),f). map(c,(fm1;fm2;fm3),6). -in((am11;am12;am21),a). map(c,(am11;am12;am21),6). -in((am22;am31;am32),a). map(c,(am22;am31;am32),6). -in(E,o) :- in(E,(f;a)). map(c,(pm1;pm2;pm3),12). -in((pm1;pm2;pm3),p). map(c,im,15). - map(c,msc,30). - -% m % s -in(E,m) :- in(E,(b;f;a;p)). map(s,bm1,w;s,bm2,s;s,bm3,w). -in((im;msc),m). map(s,(fm1;fm2;fm3),w). - map(s,(am11;am12;am21),e). - map(s,(am22;am31;am32),e). -%* e *% map(s,(pm1;pm2;pm3),e). -in(fm1,e). map(s,(im1;msc1),e). - - % l and u - map(l,b,27;l,o,24;l,p,24;l,m,120). - map(u,b,27;u,o,24;u,p,24;u,m,120). - -% global constraints -card(e,leq,2). equal(int(s,f),e). -sum(int(H,s),c,bw,(L,U)) :- H = (b;o;p;m), map(l,H,L), map(u,H,U). -in(im,gc3). in(msc,gc3). subseteq(gc3,s). - -% temporal constraints -in(msc,tc4). sum(before(tc4),c,geq,90). - -% recommendations - -recommend(bm1,am11). -recommend(am11,am12). -recommend(am11,pm1). -recommend(am12,pm1). - -recommend(bm2,am21). -recommend(am21,am22). -recommend(am21,pm2). -recommend(am22,pm2). - -recommend(bm3,am31). -recommend(am31,am32). -recommend(am31,pm3). -recommend(am32,pm3). - - - -%* -% Examination tasks - -% Ep -in((822211;822311;822411;822511;556111;556211;822611;822711;556311),ep). - -% Es -in((555813;821912;555913;555914;822012;556012;822112),es). - -% ep -map(ep,am11,am11epset;ep,am21,am21epset;ep,am22,am22epset;ep,am31,am31epset; -ep,am32,am32epset;ep,pm1,pm1epset;ep,pm2,pm2epset;ep,pm3,pm3epset;ep,am12,am12epset). - -% es -map(es,bm2,bm2esset;es,bm1,bm1esset;es,bm3,bm3esset; -es,fm1,fm1esset;es,fm2,fm2esset;es,fm3,fm3esset). - - in((822211;822311),s1). - in(s1,am11epset). - - in(822311,s3). - in(s3,am12epset). - - in(822411,s2). - in(s2,am21epset). - - in(822511,s4). - in(s4,am22epset). - - in(556111,s5). - in(s5,am31epset). - - in(556211,s6). - in(s6,am32epset). - - in(822611,s7). - in(s7,pm1epset). - - in(822711,s8). - in(s8,pm2epset). - - in(556311,s9). - in(s9,pm3epset). - - - in(821912,bm1esset). - in(555813,bm2esset). - in((555913;555914),bm3esset). - in(822012,fm1esset). - in(556012,fm2esset). - in(822112,fm3esset). - -% d - -*% \ No newline at end of file diff --git a/new/instance/cogsys.lp b/new/instance/cogsys.lp deleted file mode 100644 index 44e9e72..0000000 --- a/new/instance/cogsys.lp +++ /dev/null @@ -1,28 +0,0 @@ -% b, f, a, o and p % c -in((bm1;bm2;bm3),b). map(c,(bm1;bm2;bm3),9). -in((fm1;fm2;fm3),f). map(c,(fm1;fm2;fm3),6). -in((am11;am12;am21),a). map(c,(am11;am12;am21),6). -in((am22;am31;am32),a). map(c,(am22;am31;am32),6). -in(E,o) :- in(E,(f;a)). map(c,(pm1;pm2;pm3),12). -in((pm1;pm2;pm3),p). map(c,im,15). - map(c,msc,30). - -% m % s -in(E,m) :- in(E,(b;f;a;p)). map(s,bm1,w;s,bm2,s;s,bm3,w). -in((im;msc),m). map(s,(fm1;fm2;fm3),w). - map(s,(am11;am12;am21),e). - map(s,(am22;am31;am32),e). -%* e *% map(s,(pm1;pm2;pm3),e). -in(fm1,e). map(s,(im1;msc1),e). - - % l and u - map(l,b,27;l,o,24;l,p,24;l,m,120). - map(u,b,27;u,o,24;u,p,24;u,m,120). - -% global constraints -card(e,leq,2). equal(int(s,f),e). -sum(int(H,s),c,bw,(L,U)) :- H = (b;o;p;m), map(l,H,L), map(u,H,U). -in(im,gc3). in(msc,gc3). subseteq(gc3,s). - -% temporal constraints -in(msc,tc4). sum(before(tc4),c,geq,90). diff --git a/new/instance/cscbsc.lp b/new/instance/cscbsc.lp deleted file mode 100644 index 8ad2b5e..0000000 --- a/new/instance/cscbsc.lp +++ /dev/null @@ -1,87 +0,0 @@ -% x and y are the minimum and maximum number of focuses allowable -#const x=1. -#const y=2. - -% i, ii, iii, iv, v, vi and x -in((inf1010;inf1011;inf1020;inf1021;inf1030;inf1031;inf1040; - inf1050;inf1060;inf1070;inf1080;mat1100;mat1101;mat1102; - mat1103;inf6010;inf6030),i). -in((inf2010;inf2020;inf2021;inf2030;inf2031;inf2040;inf2041; - inf2050;inf2060;inf2061;inf2070;inf2080;inf2090;inf2091),ii). -% iii, b, c, ge, k and p -in(M,iii) :- in(M,(b;c;ge;k;p)). - in(biobm105,b). - in(chea1nf,c). - in(gewbp01,ge). - in(psybs013,k). - in(phy131c,p). -% iv, ba, ca, gea, ka and pa -in(M,iv) :- in(M,(ba;ca;gea;ka;pa)). - in((biobm107;biobm108;bioam212;bioam302;bioam314),ba). - in((cheocgee;cheawp23;cheawp3;chea8cs),ca). - in((gewbp02;gewgis1;geekl;geehy;gewbwp01;gewbwp02;gewbwp05),gea). - in((psybs011;psybs012;linbs101;linbs102;linbs103;linbs061),ka). - in((phy131d;phy511las;phy611las;phy101geo;phy201geo;phy531),pa). -in(matd230cs,v). -in((inf6020;bamaO1;bamaO2;bamaO3),vi). - -in(M,x) :- in(M,(iii;iv)). - -% m -in(E,m) :- in(E,(i;ii;iii;iv;v;vi;x)). -in(bsc,m). - - -%c -map(c,(inf1010;inf1011;inf1020;inf1021;inf1030;inf1031;inf1040; - inf1050;inf1060;inf1070;inf1080;mat1100;mat1101;mat1102; - mat1103;inf6010;inf6030;inf2010;inf2020;inf2021;inf2030; - inf2031;inf2040;inf2041;inf2050;inf2060;inf2061;inf2070; - inf2080;inf2090;inf2091;biobm105;chea1nf;gewbp01;phy131c; - biobm107;biobm108;bioam212;bioam302;bioam314;cheocgee; - cheawp23;cheawp3;chea8cs;gewbp02;gewgis1;geekl;geehy; - gewbwp01;gewbwp02;gewbwp05;linbs101;linbs102;linbs103; - linbs061;phy131d;phy511las;phy611las;phy101geo;phy201geo;phy531; - matd230cs;bamaO1;bamaO2;bamaO3),6). -map(c,(psybs011;psybs012;psybs013),9). -map(c,(inf6020;bsc),12). - - -% l and u -map(l,i,102;l,ii,12;l,v,6;l,vi,18;l,x,30;l,m,180). -map(u,i,102;u,ii,12;u,v,6;u,vi,18;u,x,30;u,m,180). - -% s -map(s,(bioam314;biobm105;chea1nf;gewbp01;gewbwp01;gewbwp05; - gewgis1;inf1010;inf1020;inf1030;inf1031;inf1060;inf1060; - inf1080;inf2020;inf2021;inf2031;inf2041;inf2061;linbs101; - mat1100;mat1101;matd230cs;phy101geo;phy131c;phy131d;phy511las),w). -map(s,(bioam212;biobm107;biobm108;chea8cs;cheawp23;cheawp3; - gewbp02;gewbwp02;inf1011;inf1021;inf1040;inf1050;inf1070; - inf2010;inf2030;inf2040;inf2050;inf2060;inf2070;inf2080; - inf6010;linbs103;mat1102;mat1103;phy201geo;phy611las),s). -map(s,(bioam302;cheocgee;geehy;geekl;inf2090;inf2091;inf6020; - inf6030;linbs061;linbs102;phy531;psybs011;psybs012;psybs013; - bamaO1;bamaO2;bamaO3),e). - -% f -in((bioinformatics;chemistry;geoscience;cognitivesciences;physics),f). - -% h -in((b;ba),biset;(c;ca),chset;(ge;gea),geset;(k;ka),coset;(p;pa),phset). -map(h,bioinformatics,biset;h,chemistry,chset;h,geoscience,geset;h,cognitivesciences,coset;h,physics,phset). - - -% global constraints -card(h,bw,(x,y)). -sum(int(Z,s),c,bw,(L,U)) :- Z = (i;ii;v;vi;m), map(l,Z,L), map(u,Z,U). -in(M,gc2) :- in(F,h), in(F,f), map(h,F,Fs), in(V,Fs), in(M,V). -sum(int(Z,s),c,bw,(L,U)) :- Z = gc2, map(l,x,L), map(u,x,U). -in(inf6020,gc3). in(bsc,gc3). subseteq(gc3,s). - -% temporal constraints -in(bsc,tc4). sum(before(tc4),c,geq,126). - - -% focus input -in((bioinformatics;physics),h). \ No newline at end of file diff --git a/new/instance/cscmsc.lp b/new/instance/cscmsc.lp deleted file mode 100755 index 48f0cfb..0000000 --- a/new/instance/cscmsc.lp +++ /dev/null @@ -1,92 +0,0 @@ -% x and y are the minimum and maximum number of focuses allowable -#const x=1. -#const y=1. - -% i, ii, iii, iv, x, a, b, c, ge, k, ma and p -in((inf7010;inf7020;inf7030;inf7040;inf7060;inf7061;inf7070;inf7080),i). -in((inf10010;inf10020),ii). -in((inf8010;inf8011;inf8020;inf8021;inf8030;inf8031;inf8032;inf8033; - inf8040;inf8041;inf8050;inf8060;inf8061;inf8062;inf8063;inf8070; - inf8072;inf8080;inf8090;inf8091),iii). -in(M,iv) :- in(M,(x;a)). -in((biobm108;chea14;chea1nf;cheocgee;chea8cs;gewbp01;phy131c;csema013),x). -in((inf9010;inf9011),a). -in((biombip03;biombip04;matmbip05;biombiw03;biombiw04;biombiw05;biombiw08),b). -in((cheb1;cheb6;che15cs),c). -in((gewrcm01;gewrcm02;gewrsm01;gewrsm02),ge). -in((csema011;csema014),k). -in((matvmd837;matvmd838;matvmd844;matdsam2a),ma). -in((phy541b;phyastcs;phy541e;phyklics),p). - -% m -in(E,m) :- in(E,(i;ii;iii;iv;x;a;b;c;ge;k;ma;p)). -in(msc,m). - -% e -in((chea14;gewbp01;inf9011),e). - -%c -map(c,(inf7010;inf7020;inf7030;inf7040;inf7060;inf7061;inf7070;inf7080; - inf10020;inf8010;inf8011;inf8020;inf8021;inf8030;inf8031;inf8032;inf8033; - inf8040;inf8041;inf8050;inf8060;inf8061;inf8062;inf8063;inf8070; - inf8072;inf8080;inf8090;inf8091;biobm108;chea14;chea1nf;cheocgee; - chea8cs;gewbp01;phy131c;csema013;inf9010;inf9011;biombip03;biombip04; - matmbip05;biombiw03;biombiw04;biombiw05;biombiw08; - cheb1;cheb6;che15cs;gewrcm01;gewrcm02;gewrsm01;gewrsm02),6). -map(c,(csema011;csema014;matvmd837;matvmd838;matvmd844;matdsam2a;phy541b; - phyastcs;phy541e;phyklics),9). -map(c,inf10010,12). -map(c,msc,30). - - -% l and u -map(l,i,12;l,ii,18;l,iii,18;l,iv,24;l,x,0;l,b,18;l,c,18;l,ge,18;l,k,18;l,ma,18;l,p,18;l,m,120). -map(u,i,12;u,ii,18;u,iii,18;u,iv,24;u,x,12;u,b,18;u,c,18;u,ge,18;u,k,18;u,ma,18;u,p,18;u,m,120). - -% s -map(s,(biombip03;biombiw04;biombiw08;chea14;chea1nf;cheb1;csema011;gewbp01; - gewrcm01;gewrcm02;inf7010;inf7060;inf7070;inf7080;inf8011;inf8021;inf8030; - inf8031;inf8061;inf8062;inf8072;inf8080;matvmd837;matvmd844;phy131c;phy541e - ),w). -map(s,(biobm108;biombip04;biombiw03;biombiw05;chea8cs;csema013;gewrsm01; - gewrsm02;inf7030;inf7040;inf8010;inf8020;inf8032;inf8033;inf8040; - inf8050;inf8060;inf8063;inf8070;matdsam2a;matmbip05;matvmd838),s). -map(s,(che15cs;cheb6;cheocgee;csema014;inf10010;inf10020;inf7020;inf7061; - inf8041;inf8090;inf8091;inf9010;inf9011;phy541b;phyastcs;phyklics),e). - -% f -in((bioinformatics;chemistry;geoscience;cognitivesciences;mathematics;physics),f). - -% h -in(b,biset;c,chset;ge,geset;k,coset;ma,maset;p,phset). -map(h,bioinformatics,biset;h,chemistry,chset;h,geoscience,geset;h,cognitivesciences,coset;h,mathematics,maset;h,physics,phset). - - -% global constraints -card(h,bw,(x,y)). -in(E,gc1) :- in(E,e). -subseteq(gc1,s). -in(M,gc1b) :- in(M,e), in(M,x). -sum(int(H,s),c,bw,(L,U)) :- H = gc1b, map(l,x,L), map(u,x,U). - -in(E,gc2) :- in(E,e), in(E,a). -subseteq(gc2,s). - -sum(int(Z,s),c,bw,(L,U)) :- Z = (ii;m), map(l,Z,L), map(u,Z,U). -sum(int(Z,s),c,geq,L) :- Z = (i;iii;V), map(l,Z,L), in(F,h), map(h,F,Fs), in(V,Fs). - -lsum(S) :- S' = #sum{L,RG: map(l,RG,L), RG = (i;iii;V), in(F,h), map(h,F,Fs), in(V,Fs)}, S = S' + L', map(l,iv,L'). -usum(S) :- S' = #sum{U,RG: map(u,RG,U), RG = (i;iii;V), in(F,h), map(h,F,Fs), in(V,Fs)}, S = S' + U', map(u,iv,U'). -in(M,gc5) :- in(F,h), map(h,F,Fs), in(V,Fs), in(M,H), H=(i;iii;iv;V). -sum(int(V,s),c,bw,(L,U)) :- V = gc5, lsum(L), usum(U). - -in(gewrcm02,gc6) :- in(F,h), F=geoscience. -subseteq(gc6,s). -in(msc,gc7). subseteq(gc7,s). - -% temporal constraints -in(msc,tc4). sum(before(tc4),c,geq,72). - - -% focus input -in((bioinformatics),h). diff --git a/new/instance/dsmsc.lp b/new/instance/dsmsc.lp deleted file mode 100644 index 54c1a93..0000000 --- a/new/instance/dsmsc.lp +++ /dev/null @@ -1,51 +0,0 @@ - -% c, r, i and ba -in((infdsc1;matvmd837;matvmd838;infdsc2;infdsc3;infdsc4),c). -in((infdsrma;infdsrmb),r). -in((infdsam1a;infdsam1b;matdsam2a;matdsam2b;matdsam3a;matdsam3b; - infdsam4a;infdsam4b;infdsam5a;infdsam5b;infdsam6a;infdsam6b; - infdsam7;matdsam8a;matdsam8b;infdsam9;infdsam10;infdsam11;bm3),i). -in((fm2;matdsbm1),ba). -in(M,l) :- in(M,(i;ba)). - -% m -in(E,m) :- in(E,(c;r;i;ba)). -in(msc,m). - -% e -in((fm2;matdsbm1),e). - -%c -map(c,(infdsc1;matvmd837;matvmd838;infdsc3; - infdsam1a;matdsam2a;matdsam3a;infdsam5a;infdsam6a; - matdsam8a;bm3),9). -map(c,(infdsc2;infdsc4;infdsam1b;matdsam2b;matdsam3b; - infdsam4a;infdsam4b;infdsam5b;infdsam6b; - infdsam7;matdsam8b;infdsam9;infdsam10;fm2;matdsbm1),6). -map(c,(infdsrma;infdsam11),12). -map(c,infdsrmb,15). -map(c,msc,30). - -% l and u -map(l,c,48;l,r,12;l,l,27;l,m,120). -map(u,c,48;u,r,15;u,l,30;u,m,120). - -% s -map(s,(bm3;fm2;infdsam1a;infdsam1b;infdsam5b;infdsam6a;infdsc3; - infdsc4;matdsam3a;matdsam3b;matdsam8b;matdsbm1;matvmd837),w). -map(s,(infdsam10;infdsam5a;infdsam6b;infdsam7;infdsc1;matdsam2a; - matdsam2b;matvmd838),s). -map(s,(infdsam11;infdsam4a;infdsam4b;infdsam9;infdsc2;infdsrma;infdsrmb; - matdsam8a),e). - -% B -b(infdsam1a,infdsam1b;matdsam2a,matdsam2b;matdsam3a,matdsam3b; - infdsam4a,infdsam4b;infdsam5a,infdsam5b;infdsam6a,infdsam6b; - matdsam8a,matdsam8b). - -% global constraints -card(e,leq,2). equal(int(s,ba),e). -sum(int(Z,s),c,bw,(L,U)) :- Z = (c;r;l;m), map(l,Z,L), map(u,Z,U). - -% temporal constraints -in(msc,tc4). sum(before(tc4),c,geq,72). diff --git a/new/instance/irsba.lp b/new/instance/irsba.lp deleted file mode 100644 index 7595bc9..0000000 --- a/new/instance/irsba.lp +++ /dev/null @@ -1,72 +0,0 @@ -% x and y are the minimum and maximum number of focuses allowable -#const x=1. -#const y=1. - -% i, ii, l, p and e -in((slrba014;slrba001;slrba002;slrba003;slrba006;rusba001; - bbmvwl110;bbmpuv610;bbmpuv110;bbmpuv210;bbmpuv310;bbmpuv410; - bbmpuv510;bbmvwl210;slrba022;slrba023;rusba002;zruba01; - zruba02;slrba017;zruba04;rusba003;slrba021),i). -in((bamaO1;bamaO2;bamaO3;bamaO4;bamaO5;bamaO6; - bamaO7;bamaO8;zruos01;zruos02;zruos03),ii). -in((slrba010;slrba012;rusba005),l). -in((bbmvwl310;bbmvwl320;rusba004),p). -in((bvmpuv110;bvmpuv210;bvmpuv120;bvmpuv220;bvmpuv310;bvmpuv320; - bvmpuv410;bvmpuv420;bvmpuv510;bvmpuv520),e). -% m -in(E,m) :- in(E,(i;ii;l;p;e)). -in(ba,m). - -%c -map(c,(slrba001;slrba002;bbmvwl110;bbmpuv610;bbmpuv110;bbmpuv210; - bbmpuv310;bbmpuv410;bbmpuv510;bbmvwl210;slrba022;slrba023; - slrba017;zruba04;rusba003;bamaO1;bamaO2;bamaO3; - bamaO4;bamaO5;bamaO6;bamaO7;bamaO8;zruos01; - zruos02;zruos03;rusba005;bbmvwl310;bbmvwl320;rusba004; - bvmpuv110;bvmpuv210;bvmpuv120;bvmpuv220;bvmpuv310;bvmpuv320; - bvmpuv410;bvmpuv420;bvmpuv510;bvmpuv520),6). -map(c,(slrba006;rusba001;rusba002;zruba01;zruba02),9). -map(c,(slrba014;slrba003;slrba010;slrba012),12). -map(c,slrba021,24). -map(c,ba,9). - -% l and u -map(l,i,183;l,ii,18;l,l,30;l,p,18;l,e,12;l,m,240). -map(u,i,183;u,ii,18;u,l,30;u,p,18;u,e,12;u,m,240). - -% s -map(s,(bbmpuv110;bbmpuv210;bbmpuv410;bbmpuv610;bbmvwl110;bbmvwl210; - bbmvwl320;rusba001;rusba002;rusba003;rusba004;rusba005; - slrba022;zruos01;zruos02),w). -map(s,(bbmpuv310;bbmpuv510;bbmvwl310;slrba021;slrba023),s). -map(s,(bvmpuv110;bvmpuv120;bvmpuv210;bvmpuv220;bvmpuv310;bvmpuv320; - bvmpuv410;bvmpuv420;bvmpuv510;bvmpuv520;slrba001;slrba002; - slrba003;slrba006;slrba010;slrba012;slrba014;slrba017; - zruba01;zruba02;zruba04;zruos03;bamaO1;bamaO2; - bamaO3;bamaO4;bamaO5;bamaO6;bamaO7;bamaO8),e). - -% D -d(zruba01,rusba001;zruba01,rusba002;zruba01,rusba003; - zruba01,rusba004;zruos03,slrba003;zruos03,slrba006; - zruos03,slrba010;zruos03,slrba012;zruos03,slrba017; - zruba01,slrba021;zruos03,zruba02;zruba01,zruba02; - zruba02,zruba04). - -% f -in((language;politics),f). - -% h -in(l,lset;(p;e),pset). -map(h,language,lset;h,politics,pset). - -% global constraints -card(h,bw,(x,y)). -sum(int(H,s),c,bw,(L,U)) :- H = (i;ii;m;V), in(F,f), in(F,h), map(h,F,Fs), in(V,Fs), map(l,H,L), map(u,H,U). -in(ba,gc2). subseteq(gc2,s). - -% temporal constraints -in(ba,tc4). sum(before(tc4),c,geq,171). - - -% focus input -in((language),h). diff --git a/new/instance/irsba_with_embedded_script.lp b/new/instance/irsba_with_embedded_script.lp deleted file mode 100755 index 25802f4..0000000 --- a/new/instance/irsba_with_embedded_script.lp +++ /dev/null @@ -1,69 +0,0 @@ -#include "embedded.lp". - -% x and y are the minimum and maximum number of focuses allowable -#const x=1. -#const y=1. - -% i, ii, l, p and e -in((slrba014;slrba001;slrba002;slrba003;slrba006;rusba001; - bbmvwl110;bbmpuv610;bbmpuv110;bbmpuv210;bbmpuv310;bbmpuv410; - bbmpuv510;bbmvwl210;slrba022;slrba023;rusba002;zruba01; - zruba02;slrba017;zruba04;rusba003;slrba021),i). -in((bamaO1;bamaO2;bamaO3;bamaO4;bamaO5;bamaO6; - bamaO7;bamaO8;zruos01;zruos02;zruos03),ii). -in((slrba010;slrba012;rusba005),l). -in((bbmvwl310;bbmvwl320;rusba004),p). -in((bvmpuv110;bvmpuv210;bvmpuv120;bvmpuv220;bvmpuv310;bvmpuv320; - bvmpuv410;bvmpuv420;bvmpuv510;bvmpuv520),e). -% m -in(E,m) :- in(E,(i;ii;l;p;e)). -in(ba,m). - -%c -map(c,(slrba001;slrba002;bbmvwl110;bbmpuv610;bbmpuv110;bbmpuv210; - bbmpuv310;bbmpuv410;bbmpuv510;bbmvwl210;slrba022;slrba023; - slrba017;zruba04;rusba003;bamaO1;bamaO2;bamaO3; - bamaO4;bamaO5;bamaO6;bamaO7;bamaO8;zruos01; - zruos02;zruos03;rusba005;bbmvwl310;bbmvwl320;rusba004; - bvmpuv110;bvmpuv210;bvmpuv120;bvmpuv220;bvmpuv310;bvmpuv320; - bvmpuv410;bvmpuv420;bvmpuv510;bvmpuv520),6). -map(c,(slrba006;rusba001;rusba002;zruba01;zruba02),9). -map(c,(slrba014;slrba003;slrba010;slrba012),12). -map(c,slrba021,24). -map(c,ba,9). - -% l and u -map(l,i,183;l,ii,18;l,l,30;l,p,18;l,e,12;l,m,240). -map(u,i,183;u,ii,18;u,l,30;u,p,18;u,e,12;u,m,240). - -% s -map(s,(bbmpuv110;bbmpuv210;bbmpuv410;bbmpuv610;bbmvwl110;bbmvwl210; - bbmvwl320;rusba001;rusba002;rusba003;rusba004;rusba005; - slrba022;zruos01;zruos02),w). -map(s,(bbmpuv310;bbmpuv510;bbmvwl310;slrba021;slrba023),s). -map(s,(bvmpuv110;bvmpuv120;bvmpuv210;bvmpuv220;bvmpuv310;bvmpuv320; - bvmpuv410;bvmpuv420;bvmpuv510;bvmpuv520;slrba001;slrba002; - slrba003;slrba006;slrba010;slrba012;slrba014;slrba017; - zruba01;zruba02;zruba04;zruos03;bamaO1;bamaO2; - bamaO3;bamaO4;bamaO5;bamaO6;bamaO7;bamaO8),e). - -% D -d(zruba01,rusba001;zruba01,rusba002;zruba01,rusba003; - zruba01,rusba004;zruos03,slrba003;zruos03,slrba006; - zruos03,slrba010;zruos03,slrba012;zruos03,slrba017; - zruba01,slrba021;zruos03,zruba02;zruba01,zruba02; - zruba02,zruba04). - -% global constraints -sum(int(H,s),c,bw,(L,U)) :- H = (i;ii;m;H'), f(F), map(h,H',F), map(l,H,L), map(u,H,U), F=@separate(fs). -in(ba,gc2). subseteq(gc2,s). - -% temporal constraints -in(ba,tc4). sum(before(tc4),c,geq,171). - -% specializations -map(h,l,llc;h,(p;e),pae). - -f(llc;pae). - -focus :- f(F). \ No newline at end of file diff --git a/new/ui.lp b/new/ui.lp deleted file mode 100644 index db39033..0000000 --- a/new/ui.lp +++ /dev/null @@ -1,57 +0,0 @@ -semester(1..n). - -elem(w, window, root). -attr(w, flex_direction, row). - - elem(s(I), container, w):-semester(I). - attr(s(I), order, I):-semester(I). - - elem(s_t(I), container, s(I)):-semester(I). - attr(s_t(I), order, 1):-semester(I). - attr(s_t(I), class, ("bg-primary";"bg-opacity-50";"fw-bold";"p-2";"m-1")):-semester(I). - - elem(s_l(I), label, s_t(I)):-semester(I). - attr(s_l(I), label, @concat("Semester ",I)):-semester(I). - attr(s_l(I), order, 1):-semester(I). - - elem(s_dd(I), dropdown_menu, s_t(I)):-semester(I). - attr(s_dd(I), order, 2):-semester(I). - attr(s_dd(I), selected, "Assign module"):-semester(I). - attr(s_dd(I), class, ("btn-sm";"btn-info")):-semester(I). - - elem(s_ddi(I,E), dropdown_menu_item, s_dd(I)):-_any(in(E,s(I))), not _all(in(E,s(I))). - attr(s_ddi(I,E), label, E):-_any(in(E,s(I))), not _all(in(E,s(I))). - when(s_ddi(I,E), click, call, add_assumption(in(E,s(I)))):-_any(in(E,s(I))), not _all(in(E,s(I))). - - elem(s_modules(I), container, s(I)):-semester(I). - attr(s_modules(I), class, ("bg-white")):-semester(I). - attr(s_modules(I), order, 2):-semester(I). - - shown_module(E,I):-_all(in(E,s(I))). - shown_module(E,I):-in(E,s(I)),_clinguin_browsing. - - elem(s_module(I,E), container, s_modules(I)):-shown_module(E,I). - attr(s_module(I,E), height, C*10):-shown_module(E,I), map(c,E,C). - attr(s_module(I,E), class, ("bg-info";"bg-opacity-50"; - "d-flex";"flex-row";"justify-content-between";"align-items-center"; - "p-2";"m-1")):-shown_module(E,I). - - elem(s_module_l(I,E), label, s_module(I,E)):-shown_module(E,I). - attr(s_module_l(I,E), label, E):-shown_module(E,I). - - elem(s_module_b(I,E), button, s_module(I,E)):-_clinguin_assume(in(E,s(I))). - attr(s_module_b(I,E), icon, "fa-times"):-_clinguin_assume(in(E,s(I))). - attr(s_module_b(I,E), class, ("btn-sm";"btn-outline")):-_clinguin_assume(in(E,s(I))). - when(s_module_b(I,E), click, call, remove_assumption(in(E,s(I)))):-_clinguin_assume(in(E,s(I))). - - -elem(menu_bar, menu_bar, w). -attr(menu_bar, title, "Study Regulations"). -attr(menu_bar, icon, "fa-graduation-cap"). - -elem(menu_bar_next, button, menu_bar). -attr(menu_bar_next, label, "Next"). -attr(menu_bar_next, icon, "fa-forward-step"). -when(menu_bar_next, click, call, next_solution). - - diff --git a/old/README.md b/old/README.md deleted file mode 100644 index db26aca..0000000 --- a/old/README.md +++ /dev/null @@ -1,19 +0,0 @@ -## Study regulations - -- **Backend**: `ClingoMultishotBackend` -- **Frontend**: `Angular` - -Create a study plan. - -These encoding was presented in the article [1] - -### Usage - -``` -clinguin client-server --domain-files old/instance.lp old/encoding.lp --ui-files old/ui.lp -c n=4 -``` - -![](out.png) - - -[1] Hahn, S., Martens, C., Nemes, A., Otunuya, H., Romero, J., Schaub, T., & Schellhorn, S. (2023). Reasoning about Study Regulations in Answer Set Programming (Preliminary Report). In ICLP Workshops (Vol. 3437) diff --git a/old/out.png b/old/out.png deleted file mode 100644 index f731fd4..0000000 Binary files a/old/out.png and /dev/null differ diff --git a/old/ui.lp b/old/ui.lp deleted file mode 100644 index db39033..0000000 --- a/old/ui.lp +++ /dev/null @@ -1,57 +0,0 @@ -semester(1..n). - -elem(w, window, root). -attr(w, flex_direction, row). - - elem(s(I), container, w):-semester(I). - attr(s(I), order, I):-semester(I). - - elem(s_t(I), container, s(I)):-semester(I). - attr(s_t(I), order, 1):-semester(I). - attr(s_t(I), class, ("bg-primary";"bg-opacity-50";"fw-bold";"p-2";"m-1")):-semester(I). - - elem(s_l(I), label, s_t(I)):-semester(I). - attr(s_l(I), label, @concat("Semester ",I)):-semester(I). - attr(s_l(I), order, 1):-semester(I). - - elem(s_dd(I), dropdown_menu, s_t(I)):-semester(I). - attr(s_dd(I), order, 2):-semester(I). - attr(s_dd(I), selected, "Assign module"):-semester(I). - attr(s_dd(I), class, ("btn-sm";"btn-info")):-semester(I). - - elem(s_ddi(I,E), dropdown_menu_item, s_dd(I)):-_any(in(E,s(I))), not _all(in(E,s(I))). - attr(s_ddi(I,E), label, E):-_any(in(E,s(I))), not _all(in(E,s(I))). - when(s_ddi(I,E), click, call, add_assumption(in(E,s(I)))):-_any(in(E,s(I))), not _all(in(E,s(I))). - - elem(s_modules(I), container, s(I)):-semester(I). - attr(s_modules(I), class, ("bg-white")):-semester(I). - attr(s_modules(I), order, 2):-semester(I). - - shown_module(E,I):-_all(in(E,s(I))). - shown_module(E,I):-in(E,s(I)),_clinguin_browsing. - - elem(s_module(I,E), container, s_modules(I)):-shown_module(E,I). - attr(s_module(I,E), height, C*10):-shown_module(E,I), map(c,E,C). - attr(s_module(I,E), class, ("bg-info";"bg-opacity-50"; - "d-flex";"flex-row";"justify-content-between";"align-items-center"; - "p-2";"m-1")):-shown_module(E,I). - - elem(s_module_l(I,E), label, s_module(I,E)):-shown_module(E,I). - attr(s_module_l(I,E), label, E):-shown_module(E,I). - - elem(s_module_b(I,E), button, s_module(I,E)):-_clinguin_assume(in(E,s(I))). - attr(s_module_b(I,E), icon, "fa-times"):-_clinguin_assume(in(E,s(I))). - attr(s_module_b(I,E), class, ("btn-sm";"btn-outline")):-_clinguin_assume(in(E,s(I))). - when(s_module_b(I,E), click, call, remove_assumption(in(E,s(I)))):-_clinguin_assume(in(E,s(I))). - - -elem(menu_bar, menu_bar, w). -attr(menu_bar, title, "Study Regulations"). -attr(menu_bar, icon, "fa-graduation-cap"). - -elem(menu_bar_next, button, menu_bar). -attr(menu_bar_next, label, "Next"). -attr(menu_bar_next, icon, "fa-forward-step"). -when(menu_bar_next, click, call, next_solution). - - diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7c08e4f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,40 @@ +anyio==3.7.1 +attrs==24.2.0 +autoflake==2.3.1 +cffi==1.17.1 +click==8.1.7 +clingexplaid==1.0.14 +clingo==5.7.1 +clingo-dl==1.5.0.post1 +clingraph==1.1.2 +clinguin==2.0.0 +Clorm==1.6.0 +exceptiongroup==1.2.2 +fastapi==0.103.2 +graphviz==0.20.3 +h11==0.14.0 +idna==3.10 +Jinja2==3.1.4 +jsonschema==4.23.0 +jsonschema-specifications==2023.12.1 +linkify-it-py==2.0.3 +markdown-it-py==3.0.0 +MarkupSafe==2.1.5 +mdit-py-plugins==0.4.2 +mdurl==0.1.2 +networkx==3.2.1 +pillow==10.4.0 +pycparser==2.22 +pydantic==1.10.2 +pyflakes==3.2.0 +Pygments==2.18.0 +referencing==0.35.1 +rich==13.9.2 +rpds-py==0.20.0 +sniffio==1.3.1 +starlette==0.27.0 +textual==0.65.1 +tomli==2.0.2 +typing_extensions==4.12.2 +uc-micro-py==1.0.3 +uvicorn==0.31.0 diff --git a/ui/exams.lp b/ui/exams.lp new file mode 100644 index 0000000..4d4bbe5 --- /dev/null +++ b/ui/exams.lp @@ -0,0 +1,182 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Main Structure and Header +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +elem(exam_info_column(E), container, module_info_section(E)) :- + examination(_,_,_,_,E,_). +attr(exam_info_column(E), class, ("flex-grow-1"; "w-50")) :- + examination(_,_,_,_,E,_). +attr(exam_info_column(E), order, 2) :- + examination(_,_,_,_,E,_). + +elem(exam_header(E), container, exam_info_column(E)) :- + examination(_,_,_,_,E,_). +attr(exam_header(E), class, ("mb-3"; "p-3"; "bg-white"; "rounded"; "shadow-sm")) :- + examination(_,_,_,_,E,_). +attr(exam_header(E), order, 1) :- + examination(_,_,_,_,E,_). + +elem(exam_header_label(E), label, exam_header(E)) :- + examination(_,_,_,_,E,_). +attr(exam_header_label(E), label, "Examination Tasks") :- + examination(_,_,_,_,E,_). +attr(exam_header_label(E), class, ("h5"; "mb-0")) :- + examination(_,_,_,_,E,_). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Examination List +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +elem(exam_list(E), container, exam_info_column(E)) :- + examination(_,_,_,_,E,_). +attr(exam_list(E), class, ("list-group"; "shadow-sm")) :- + examination(_,_,_,_,E,_). +attr(exam_list(E), order, 2) :- + examination(_,_,_,_,E,_). + +% Individual exam items +elem(exam_item(E,ExamID), container, exam_list(E)) :- + examination(ExamID,_,_,_,E,_). +attr(exam_item(E,ExamID), class, ("list-group-item"; "d-flex"; "flex-column"; "justify-content-between"; "align-items-center"; "py-3")) :- + examination(ExamID,_,_,_,E,_). + +% Individual examination items +elem(exam_item(E, ExamID), container, exam_list(E)) :- + examination(ExamID, Form, Title, Type, E, _). +attr(exam_item(E, ExamID), class, ("list-group-item"; "d-flex"; "justify-content-between"; "align-items-center"; "py-3")) :- + examination(ExamID, _, _, _, E, _). +attr(exam_item(E, ExamID), order, ExamID) :- + examination(ExamID, _, _, _, E, _). + +% Examination title and form +elem(exam_title(E, ExamID), label, exam_item(E, ExamID)) :- + examination(ExamID, Form, Title, _, E, _). +attr(exam_title(E, ExamID), label, @concat(Title)) :- + examination(ExamID, Form, Title, _, E, _). +attr(exam_title(E, ExamID), class, ("text-wrap"; "p-2"; "fw-bold")) :- + examination(ExamID, Form, Title, _, E, _). +attr(exam_title(E, ExamID), order, 1) :- + examination(ExamID, _, _, _, E, _). + +% Examination type badge +elem(exam_type(E, ExamID), label, exam_item(E, ExamID)) :- + examination(ExamID, _, _, Type, E, _). +attr(exam_type(E, ExamID), label, Form) :- + examination(ExamID, Form, _, _, E, _). +attr(exam_type(E, ExamID), class, ("badge"; "rounded-pill"; "bg-primary"; "m-2")) :- + examination(ExamID, _, _, Type, E, _). +attr(exam_type(E, ExamID), class, "bg-success") :- + examination(ExamID, _, _, "PL", E, _). +attr(exam_type(E, ExamID), class, "bg-warning") :- + examination(ExamID, _, _, "PNL", E, _). +attr(exam_type(E, ExamID), class, "bg-info") :- + examination(ExamID, _, _, "SL", E, _). +attr(exam_type(E, ExamID), order, 2) :- + examination(ExamID, _, _, _, E, _). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Exam Task Assignment Logic +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Main dropdown structure +elem(exam_dropdown(E, ExamID), dropdown_menu, exam_item(E, ExamID)) :- + examination(ExamID, _, _, _, E, _). +attr(exam_dropdown(E, ExamID), order, 3) :- + examination(ExamID, _, _, _, E, _). + +% Basic styling +attr(exam_dropdown(E, ExamID), class, ("m-2"; "border")) :- + examination(ExamID, _, _, _, E, _). + +% Module not assigned - disable exam assignment +attr(exam_dropdown(E, ExamID), selected, "Module must be assigned first") :- + examination(ExamID, _, _, _, E, _), + not shown_module(E,_). +attr(exam_dropdown(E, ExamID), class, ("btn"; "btn-sm"; "btn-secondary"; "disabled"; "text-wrap")) :- + examination(ExamID, _, _, _, E, _), + not shown_module(E,_). + +% Default state when exam is unassigned but module is assigned +attr(exam_dropdown(E, ExamID), selected, "Assign exam to semester") :- + examination(ExamID, _, _, _, E, _), + shown_module(E,_), + not _clinguin_assume(in(ExamID, e(_)), true). +attr(exam_dropdown(E, ExamID), class, ("btn"; "btn-sm"; "btn-outline-secondary"; "text-wrap")) :- + examination(ExamID, _, _, _, E, _), + shown_module(E,_), + not _clinguin_assume(in(ExamID, e(_)), true). + +% Exam assigned state +attr(exam_dropdown(E, ExamID), selected, @concat("Exam in Semester ", I)) :- + examination(ExamID, _, _, _, E, _), + _clinguin_assume(in(ExamID, e(I)), true). +attr(exam_dropdown(E, ExamID), class, ("btn"; "btn-sm"; "btn-secondary"; "text-wrap")) :- + examination(ExamID, _, _, _, E, _), + _clinguin_assume(in(ExamID, e(_)), true). + +% Unassign option +elem(remove_exam_semester(E, ExamID), dropdown_menu_item, exam_dropdown(E, ExamID)) :- + examination(ExamID, _, _, _, E, _), + shown_module(E,_), + _clinguin_assume(in(ExamID, e(_)), true). +attr(remove_exam_semester(E, ExamID), label, "Unassign exam") :- + examination(ExamID, _, _, _, E, _), + _clinguin_assume(in(ExamID, e(_)), true). +attr(remove_exam_semester(E, ExamID), icon, "fa-ban") :- + examination(ExamID, _, _, _, E, _), + _clinguin_assume(in(ExamID, e(_)), true). +attr(remove_exam_semester(E, ExamID), class, ("text-danger"; "text-opacity-75")) :- + examination(ExamID, _, _, _, E, _), + _clinguin_assume(in(ExamID, e(_)), true). +when(remove_exam_semester(E, ExamID), click, call, remove_assumption(in(ExamID, e(I)))) :- + examination(ExamID, _, _, _, E, _), + _clinguin_assume(in(ExamID, e(I)), true). + +% Show semester options only if module is assigned +elem(exam_semester_option(E, ExamID, I), dropdown_menu_item, exam_dropdown(E, ExamID)) :- + examination(ExamID, _, _, _, E, _), + shown_module(E,_), + semester(I), + _any_opt(in(ExamID, e(I))). + +% Currently assigned semester +attr(exam_semester_option(E, ExamID, I), label, @concat("Semester ", I, " ★")) :- + examination(ExamID, _, _, _, E, _), + semester(I), + _clinguin_assume(in(ExamID, e(I)), true). + +% Available semesters +attr(exam_semester_option(E, ExamID, I), label, @concat("Semester ", I)) :- + examination(ExamID, _, _, _, E, _), + semester(I), + not _clinguin_assume(in(ExamID, e(I)), true). + +% Style available semesters +attr(exam_semester_option(E, ExamID, I), class, "text-success") :- + examination(ExamID, _, _, _, E, _), + semester(I), + _any_opt(in(ExamID, e(I))), + not _clinguin_assume(in(ExamID, e(I)), true). + +attr(exam_semester_option(E, ExamID, I), icon, "fa-face-smile") :- + examination(ExamID, _, _, _, E, _), + semester(I), + _any_opt(in(ExamID, e(I))), + not _clinguin_assume(in(ExamID, e(I)), true). + +% Style assigned semester +attr(exam_semester_option(E, ExamID, I), class, ("text-secondary"; "disabled")) :- + examination(ExamID, _, _, _, E, _), + semester(I), + _clinguin_assume(in(ExamID, e(I)), true). + +% Semester order +attr(exam_semester_option(E, ExamID, I), order, I) :- + examination(ExamID, _, _, _, E, _), + semester(I). + +% Click handler - only if module is assigned +when(exam_semester_option(E, ExamID, I), click, call, add_assumption(in(ExamID, e(I)))) :- + examination(ExamID, _, _, _, E, _), + shown_module(E,_), + semester(I), + _any_opt(in(ExamID, e(I))), + not _clinguin_assume(in(ExamID, e(I)), true). \ No newline at end of file diff --git a/ui/layout.lp b/ui/layout.lp new file mode 100644 index 0000000..5276d66 --- /dev/null +++ b/ui/layout.lp @@ -0,0 +1,25 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Main Layout Container +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +elem(main_container, container, root_window). +attr(main_container, class, ("d-flex"; "flex-column"; "flex-lg-row"; "justify-content-between"; "align-items-start"; "m-2")). +attr(main_container, child_layout, flex). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Center Section Configuration +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +elem(center_section, container, main_container). +attr(center_section, order, 1). +attr(center_section, class, ("col-12"; "col-md-12"; "col-lg-10"; "pt-3"; "mb-3"; "mb-lg-0"; "d-flex"; "justify-content-center")). +attr(center_section, child_layout, flex). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Right Section Configuration +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +elem(right_section, container, main_container). +attr(right_section, order, 2). +attr(right_section, class, ("col-12"; "col-md-12"; "col-lg-2"; "ml-lg-auto"; "mb-lg-0"; "p-3"; "d-flex"; "flex-row"; "flex-wrap"; "flex-lg-column")). +attr(right_section, child_layout, flex). \ No newline at end of file diff --git a/ui/menu_bar.lp b/ui/menu_bar.lp new file mode 100644 index 0000000..140fd24 --- /dev/null +++ b/ui/menu_bar.lp @@ -0,0 +1,36 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Main Menu Bar Configuration +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Main menu bar configuration +elem(menu_bar, menu_bar, root_window). +attr(menu_bar, title, "Study Regulations"). +attr(menu_bar, icon, "fa-graduation-cap"). + +% Button to clear all assumptions +elem(menu_bar_clear, button, menu_bar). +attr(menu_bar_clear, label, "Clear"). +attr(menu_bar_clear, icon, "fa-trash"). +attr(menu_bar_clear, class, ("btn-sm"; "btn-outline-secondary")). +when(menu_bar_clear, click, call, clear_assumptions). + +% Button to move to the next solution +elem(menu_bar_next, button, menu_bar). +attr(menu_bar_next, label, "Next"). +attr(menu_bar_next, icon, "fa-forward-step"). +attr(menu_bar_next, class, ("btn-sm"; "btn-outline-secondary")). +when(menu_bar_next, click, call, next_solution(optN)). + +% Button to select the current solution +elem(menu_bar_select, button, menu_bar). +attr(menu_bar_select, label, "Select"). +attr(menu_bar_select, icon, "fa-hand-pointer"). +attr(menu_bar_select, class, ("btn-sm"; "btn-outline-secondary")). +when(menu_bar_select, click, call, select). + +% Button to download the ASP model +elem(menu_bar_download_asp, button, menu_bar). +attr(menu_bar_download_asp, label, "Download ASP Model"). +attr(menu_bar_download_asp, icon, "fa-download"). +attr(menu_bar_download_asp, class, ("btn-sm"; "btn-outline-secondary")). +when(menu_bar_download_asp, click, call, download("#show in.", "asp_study_plan.lp")). diff --git a/ui/modals.lp b/ui/modals.lp new file mode 100644 index 0000000..39237c4 --- /dev/null +++ b/ui/modals.lp @@ -0,0 +1,222 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Modal with module information +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Modal for displaying module information +elem(module_info_modal(E), modal, root_window) :- in(E,_). +attr(module_info_modal(E), title, E) :- in(E,_). +attr(module_info_modal(E), size, "lg") :- in(E,_). +attr(module_info_modal(E), class, ("text-capitalize"; "h6")) :- in(E,_). + + % Main container for modal content + elem(module_info_container(E), container, module_info_modal(E)) :- in(E,_). + attr(module_info_container(E), class, ("p-4"; "bg-light"; "rounded")) :- in(E,_). + + % Header section + elem(module_header(E), container, module_info_container(E)) :- in(E,_). + attr(module_header(E), class, ("mb-4"; "pb-3"; "border-bottom")) :- in(E,_). + attr(module_header(E), order, 1) :- in(E,_). + + % Module title + elem(module_title(E), label, module_header(E)) :- module_program(_, EN, E, _, _). + attr(module_title(E), label, EN) :- module_program(_, EN, E, _, _). + attr(module_title(E), class, ("h4"; "fw-bold"; "mb-2")) :- module_program(_, _, E, _, _). + attr(module_title(E), order, 1) :- module_program(_, _, E, _, _). + + % Module ID + elem(module_id(E), label, module_header(E)) :- module_program(MID, _, E, _, _). + attr(module_id(E), label, @concat("Module ID: ", MID)) :- module_program(MID, _, E, _, _). + attr(module_id(E), class, ("text-muted"; "ms-2")) :- module_program(_, _, E, _, _). + attr(module_id(E), order, 2) :- module_program(_, _, E, _, _). + + % Main info section + elem(module_info_section(E), container, module_info_container(E)) :- in(E,_). + attr(module_info_section(E), class, ("d-flex"; "flex-column"; "flex-md-row"; "gap-4")) :- in(E,_). + attr(module_info_section(E), order, 2) :- in(E,_). + + % Left column: Basic information + elem(basic_info_column(E), container, module_info_section(E)) :- in(E,_). + attr(basic_info_column(E), class, ("flex-grow-1"; "w-100")) :- in(E,_), not examination(_, _, _, _, E, _). + attr(basic_info_column(E), class, ("flex-grow-1"; "w-50")) :- in(E,_), examination(_, _, _, _, E, _). + attr(basic_info_column(E), order, 1) :- in(E,_). + + % Basic info header + elem(basic_info_header(E), container, basic_info_column(E)) :- in(E,_). + attr(basic_info_header(E), class, ("mb-3"; "p-3"; "bg-white"; "rounded"; "shadow-sm")) :- in(E,_). + attr(basic_info_header(E), order, 1) :- in(E,_). + + % Basic info label + elem(basic_info_label(E), label, basic_info_header(E)) :- in(E,_). + attr(basic_info_label(E), label, "Basic Information") :- in(E,_). + attr(basic_info_label(E), class, ("h5"; "mb-0")) :- in(E,_). + + % Program information + elem(program_info(E), container, basic_info_column(E)) :- module_program(_, _, E, _, P), program(P, PN, D, V). + attr(program_info(E), class, ("mb-3"; "p-3"; "bg-white"; "rounded"; "shadow-sm")) :- module_program(_, _, E, _, _). + attr(program_info(E), order, 2) :- module_program(_, _, E, _, _). + + % Program label + elem(program_label(E), label, program_info(E)) :- module_program(_, _, E, _, P), program(P, PN, D, V). + attr(program_label(E), label, @concat("
Program: ", PN, " (", P, ")
", + "
Degree: ", D, "
", + "
Version: ", V, "
")) :- + module_program(_, _, E, _, P), program(P, PN, D, V). + + % Credits + elem(credits_info(E), container, basic_info_column(E)) :- module_program(_, _, E, C, _). + attr(credits_info(E), class, ("mb-3"; "p-3"; "bg-white"; "rounded"; "shadow-sm")) :- module_program(_, _, E, _, _). + attr(credits_info(E), order, 3) :- module_program(_, _, E, _, _). + + % Credits label + elem(credits_label(E), label, credits_info(E)) :- module_program(_, _, E, C, _). + attr(credits_label(E), label, @concat("Credits: ", C)) :- module_program(_, _, E, C, _). + + % Action section + elem(bottom_section(E), container, module_info_container(E)) :- in(E,_). + attr(bottom_section(E), class, ("pt-3"; "d-flex"; "flex-column")) :- in(E,_). + attr(bottom_section(E), order, 3) :- in(E,_). + + % Action section content + elem(action_section(E), container, bottom_section(E)) :- in(E,_). + attr(action_section(E), class, ("d-flex"; "flex-column"; "justify-content-center"; "align-items-center"; "p-4"; "bg-white"; "rounded"; "shadow-sm")) :- in(E,_). + attr(action_section(E), order, 1) :- in(E,_). + + % Preference container + elem(pref_container(E), container, action_section(E)) :- in(E,_), use_preferences. + attr(pref_container(E), class, ("d-flex"; "flex-row"; "align-items-center"; "gap-3"; "p-2")) :- in(E,_), use_preferences. + attr(pref_container(E), order, 1) :- in(E,_), use_preferences. + + % Checkbox for preferences + elem(pref_container(E,P), checkbox, pref_container(E)) :- in(E,_), preference(P,M). + attr(pref_container(E,P), label, M) :- in(E,_), preference(P,M). + attr(pref_container(E,P), checked, true) :- in(E,_), user_preference(P,E). + when(pref_container(E,P), click, call, set_external(user_preference(P,E),false)) :- in(E,_), preference(P,M), user_preference(P,E). + when(pref_container(E,P), click, call, set_external(user_preference(P,E),true)) :- in(E,_), preference(P,M), not user_preference(P,E). + when(pref_container(E,P), click, context, (modal_opened,E)) :- in(E,_), preference(P,M). + + % Disable based on conditions + attr(pref_container(E,P), disabled, true) :- in(E,_), user_preference(P',E), preference(P,_), P'!=P. + attr(pref_container(E,include(hard;soft)), disabled, true) :- in(E,_), not _any(in(E,s(_))),use_preferences. + attr(pref_container(E,exclude(hard;soft)), disabled, true) :- in(E,_), _all(in(E,s(_))),use_preferences. + % attr(pref_container(E,P), disabled, true) :- _all(in(E,s(I))), not _clinguin_assume(in(E,s(I)), true), preference(P,_). + + % Button container + elem(button_container(E), container, action_section(E)) :- in(E,_). + attr(button_container(E), class, ("d-flex"; "justify-content-center"; "align-items-center"; "gap-3"; "mb-3"; "mt-3")) :- in(E,_). + attr(button_container(E), order, 2) :- in(E,_). + + % Dropdown for assigning unassigned modules to a semester + elem(assign_semester_dropdown(E), dropdown_menu, button_container(E)) :- module_program(_, _, E, _, _). + attr(assign_semester_dropdown(E), selected, "Assign to semester") :- not _all(in(E, s(_))), module_program(_, _, E, _, _). + attr(assign_semester_dropdown(E), class, ("btn"; "btn-outline-secondary")) :- not _all(in(E, s(_))), module_program(_, _, E, _, _). + + % Show "Assigned to semester" if the module is already assigned + attr(assign_semester_dropdown(E), selected, @concat("Assigned to Semester ",I)) :- + _all(in(E, s(I))), + module_program(_, _, E, _, _). + attr(assign_semester_dropdown(E), class, ("btn"; "btn-secondary")) :- + _any(in(E, s(_))), % Module is assigned to at least one semester + _all(in(E, s(_))), % Fully assigned + module_program(_, _, E, _, _). + + % Show "Cannot be assigned" if the module cannot be assigned to any semester + attr(assign_semester_dropdown(E), selected, "Cannot be assigned") :- + not _any(in(E, s(_))), % Module is unassigned + not _any(module_addable_to_semester(E, _)), % Cannot be assigned + module_program(_, _, E, _, _). + attr(assign_semester_dropdown(E), class, ("btn"; "btn-secondary"; "disabled")) :- + not _any(in(E, s(_))), % Module is unassigned + not _any(module_addable_to_semester(E, _)), % Cannot be assigned + module_program(_, _, E, _, _). + + % Options for assigning module to a semester + elem(remove_semester_option(E), dropdown_menu_item, assign_semester_dropdown(E)) :- + module_program(_, _, E, _, _), in(E, s(I)). + attr(remove_semester_option(E), label, "Unassign Module") :- module_program(_, _, E, _, _), in(E, s(I)). + attr(remove_semester_option(E), icon, "fa-ban") :- module_program(_, _, E, _, _), in(E, s(I)). + attr(remove_semester_option(E), class, "text-danger"; "text-opacity-75") :- module_program(_, _, E, _, _), in(E, s(I)). + attr(remove_semester_option(E), class, ("disabled"; "text-danger"; "text-opacity-50")) :- module_program(_, _, E, _, _), in(E, s(I)), not _clinguin_assume(in(E, s(I)), true). + when(remove_semester_option(E), click, call, remove_assumption(in(E, s(I)))) :- module_program(_, _, E, _, _), in(E, s(I)). + + % Assign module to a semester + elem(assign_semester_option(E, I), dropdown_menu_item, assign_semester_dropdown(E)) :- + module_program(_, _, E, _, _), semester(I). + + % Display semester number with a star for the current semester + attr(assign_semester_option(E, I), label, @concat("Semester ", I, " ★")) :- + module_program(_, _, E, _, _), semester(I), _all(in(E, s(I))). + + % Display semester number for other semesters + attr(assign_semester_option(E, I), label, @concat("Semester ", I)) :- + module_program(_, _, E, _, _), semester(I), not _all(in(E, s(I))). + + % Disable current semester and style it + attr(assign_semester_option(E, I), class, ("text-secondary"; "disabled"; "text-opacity-75")) :- + module_program(_, _, E, _, _), semester(I), _any(in(E, s(I))), _all(in(E, s(_))). + + % Success color for assignable semesters + attr(assign_semester_option(E, I), class, "text-success") :- + module_program(_, _, E, _, _), semester(I), _any_opt(in(E, s(I))), not _all(in(E, s(I))). + attr(assign_semester_option(E, I), icon, "fa-face-smile") :- + module_program(_, _, E, _, _), semester(I), _any_opt(in(E, s(I))), not _all(in(E, s(I))). + + % Warning color for partially assigned modules + attr(assign_semester_option(E, I), class, "text-warning") :- + module_program(_, _, E, _, _), semester(I), _any(in(E, s(I))), not _any_opt(in(E, s(I))). + attr(assign_semester_option(E, I), icon, "fa-face-meh") :- + module_program(_, _, E, _, _), semester(I), _any(in(E, s(I))), not _any_opt(in(E, s(I))). + + % Disable semesters not meeting conditions + attr(assign_semester_option(E, I), class, ("text-dark"; "disabled"; "text-opacity-25")) :- + module_program(_, _, E, _, _), semester(I), not _any(in(E, s(I))). + attr(assign_semester_option(E, I), icon, "fa-times") :- module_program(_, _, E, _, _), semester(I), not _any(in(E, s(I))). + + % Maintain semester order + attr(assign_semester_option(E, I), order, I) :- module_program(_, _, E, _, _), semester(I), not _all(in(E, s(_))). + when(assign_semester_option(E, I), click, call, add_assumption(in(E, s(I)))) :- module_program(_, _, E, _, _), semester(I), _any(in(E, s(I))), not _all(in(E, s(_))). + + % Examination legend + elem(exam_legend(E), container, bottom_section(E)) :- in(E,_). + attr(exam_legend(E), class, ("mt-3"; "p-3"; "border-top"; "bg-light")) :- in(E,_). + attr(exam_legend(E), order, 2) :- in(E,_). + + % Examination legend header + elem(exam_legend_header(E), label, exam_legend(E)) :- in(E,_). + attr(exam_legend_header(E), label, "Examination Types:") :- in(E,_). + attr(exam_legend_header(E), class, ("fw-bold"; "pt-2"; "d-block"; "small")) :- in(E,_). + attr(exam_legend_header(E), order, 1) :- in(E,_). + + % Legend content container + elem(exam_legend_content(E), container, exam_legend(E)) :- in(E,_). + attr(exam_legend_content(E), class, ("d-flex"; "flex-row"; "gap-2"; "align-items-center")) :- in(E,_). + attr(exam_legend_content(E), order, 2) :- in(E,_). + + % PL badge + elem(exam_legend_pl_badge(E), label, exam_legend_content(E)) :- in(E,_). + attr(exam_legend_pl_badge(E), label, "PL") :- in(E,_). + attr(exam_legend_pl_badge(E), class, ("badge"; "rounded-pill"; "bg-success"; "small")) :- in(E,_). + + % PL description + elem(exam_legend_pl_text(E), label, exam_legend_content(E)) :- in(E,_). + attr(exam_legend_pl_text(E), label, "Primary Examination (graded)") :- in(E,_). + attr(exam_legend_pl_text(E), class, ("small")) :- in(E,_). + + % PNL badge + elem(exam_legend_pnl_badge(E), label, exam_legend_content(E)) :- in(E,_). + attr(exam_legend_pnl_badge(E), label, "PNL") :- in(E,_). + attr(exam_legend_pnl_badge(E), class, ("badge"; "rounded-pill"; "bg-warning"; "small")) :- in(E,_). + + % PNL description + elem(exam_legend_pnl_text(E), label, exam_legend_content(E)) :- in(E,_). + attr(exam_legend_pnl_text(E), label, "Secondary Examination") :- in(E,_). + attr(exam_legend_pnl_text(E), class, ("small")) :- in(E,_). + + % SL badge + elem(exam_legend_sl_badge(E), label, exam_legend_content(E)) :- in(E,_). + attr(exam_legend_sl_badge(E), label, "SL") :- in(E,_). + attr(exam_legend_sl_badge(E), class, ("badge"; "rounded-pill"; "bg-info"; "small")) :- in(E,_). + + % SL description + elem(exam_legend_sl_text(E), label, exam_legend_content(E)) :- in(E,_). + attr(exam_legend_sl_text(E), label, "Ungraded Academic Achievement") :- in(E,_). + attr(exam_legend_sl_text(E), class, ("small")) :- in(E,_). diff --git a/ui/modules.lp b/ui/modules.lp new file mode 100644 index 0000000..8381590 --- /dev/null +++ b/ui/modules.lp @@ -0,0 +1,101 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Dropdown Menu Items for Module Assignment + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Dropdown for assigning modules to a semester + elem(assign_module_dropdown(I), dropdown_menu, semester_header_container(I)) :- semester(I). + attr(assign_module_dropdown(I), order, 2) :- semester(I). + attr(assign_module_dropdown(I), selected, "Assign module") :- semester(I). + attr(assign_module_dropdown(I), class, ("btn-sm";"btn-outline-dark"; "m-2")) :- semester(I). + + + % Dropdown menu items to assign modules + module_addable_to_semester(E,I) :- + module_program(_, _, E, _, _), % Only use module definitions + semester(I), + not _all(in(E,s(I))). + + elem(assign_module_option(I,E), dropdown_menu_item, assign_module_dropdown(I)) :- module_addable_to_semester(E, I). + attr(assign_module_option(I,E), label, @concat(E, " (", C, " ECTS)")) :- module_addable_to_semester(E, I), map(c, E, C). + attr(assign_module_option(I,E), class, "disabled") :- module_addable_to_semester(E,I), not _any(in(E,s(I))). + attr(assign_module_option(I,E), class, "opacity-50") :- module_addable_to_semester(E,I), not _any(in(E,s(I))). + + attr(assign_module_option(I,E), class, "text-success") :- module_addable_to_semester(E, I), user_preference(include(_),E). + attr(assign_module_option(I,E), class, "text-danger") :- module_addable_to_semester(E, I), user_preference(exclude(_),E). + attr(assign_module_option(I,E), icon, ("fa-solid";"fa-thumbs-up")) :- module_addable_to_semester(E, I), user_preference(include(hard),E). + attr(assign_module_option(I,E), icon, ("fa-regular";"fa-thumbs-up")) :- module_addable_to_semester(E, I), user_preference(include(soft),E). + attr(assign_module_option(I,E), icon, ("fa-regular";"fa-thumbs-down")) :- module_addable_to_semester(E, I), user_preference(exclude(soft),E). + attr(assign_module_option(I,E), icon, ("fa-solid";"fa-thumbs-down")) :- module_addable_to_semester(E, I), user_preference(exclude(hard),E). + + when(assign_module_option(I,E), click, call, add_assumption(in(E,s(I)))) :- module_addable_to_semester(E, I). + + % Container for modules in each semester + elem(semester_modules_container(I), container, semester_container(I)) :- semester(I). + attr(semester_modules_container(I), class, ("bg-wight")) :- semester(I). + attr(semester_modules_container(I), order, 2) :- semester(I). + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Module Display within Semesters + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Display a module if assigned to a semester + shown_module(E,I) :- _all(in(E,s(I))). + shown_module(E,I) :- in(E,s(I)), _clinguin_browsing. + + % Container for displayed modules + elem(displayed_module(I,E), container, semester_modules_container(I)) :- shown_module(E,I). + attr(displayed_module(I,E), height, C*12) :- shown_module(E,I), map(c,E,C). + attr(displayed_module(I,E), width, 200) :- shown_module(E,I). + attr(displayed_module(I,E), class, ("border"; "border-secondary"; "d-flex";"flex-row";"justify-content-between";"align-items-center"; "p-3";"m-2"; "rounded"; "border-2"; "border-opacity-50"; "bg-white")) :- shown_module(E,I). + attr(displayed_module(I,E), class, "border-info") :- _all(in(E,s(I))), not _clinguin_assume(in(E,s(I)), true). + + elem(displayed_module_l(I,E), container, displayed_module(I,E)) :- shown_module(E,I). + attr(displayed_module_l(I,E), class, "text-wrap") :- shown_module(E,I). + attr(displayed_module_l(I,E), fontSize, ("12px")) :- shown_module(E,I). + + elem(displayed_module_b(I,E), container, displayed_module(I,E)) :- shown_module(E,I). + attr(displayed_module_b(I,E), class, ("align-items-end"; "ms-auto")) :- shown_module(E,I). + + % Label for each displayed module + elem(module_label(I,E), label, displayed_module_l(I,E)) :- shown_module(E,I). + attr(module_label(I,E), label, @concat(E,": ",EN)) :- shown_module(E,I), module_program(_, EN, E, _, _). + attr(module_label(I,E), class, ("text-black")) :- _clinguin_assume(in(E,s(I)), true). + attr(module_label(I,E), class, ("text-muted")) :- _all(in(E,s(I))), not _clinguin_assume(in(E,s(I)), true). + when(module_label(I,E), click, update, (module_info_modal(E), visibility, shown)) :- shown_module(E,I). + + % Button to remove a module from a semester + elem(remove_module_button(I,E), button, displayed_module_b(I,E)) :- _clinguin_assume(in(E,s(I)), true). + attr(remove_module_button(I,E), icon, "fa-times") :- _clinguin_assume(in(E,s(I)), true). + attr(remove_module_button(I,E), class, ("p-2"; "ms-auto"; "border-0"; "bg-transparent"; "text-secondary"; "small")) :- _clinguin_assume(in(E,s(I)), true). + when(remove_module_button(I,E), click, call, remove_assumption(in(E,s(I)))) :- _clinguin_assume(in(E,s(I)), true). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Display of Total Credits for Each Semester + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Container for total credits under each semester + elem(semester_credits_container(I), container, semester_container(I)) :- semester(I). + attr(semester_credits_container(I), order, 3) :- semester(I). + attr(semester_credits_container(I), class, ("p-2"; "mt-2"; "rounded"; "text-center"; "fw-bold"; "mt-auto")) :- semester(I). + + % Label to display total credits for a semester + elem(semester_credits_label(I), label, semester_credits_container(I)) :- semester(I). + attr(semester_credits_label(I), label, @concat(SC, " ECTS")) :- + semester(I), + SC = #sum{ C,E : map(c,E,C), shown_module(E,I) }. + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Display of Total Credits at the Top of the Page + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Container to display total credits across all semesters + elem(total_credits_display_container, container, semester_control_container). + attr(total_credits_display_container, order, 1). + attr(total_credits_display_container, class, ( "p-3"; "rounded"; "m-2"; "align-self-center")). + % attr(total_credits_display_container, class, ("bg-secondary"; "text-white"; "p-3"; "rounded"; "m-2"; "align-self-center";"fw-bold")). + + % Label to display total credits + elem(total_credits_label, label, total_credits_display_container). + attr(total_credits_label, label, @concat("Assigned credits: ", TC, " ECTS")) :- + TC = #sum{ C,E : map(c,E,C), shown_module(E,_) }. diff --git a/ui/semesters.lp b/ui/semesters.lp new file mode 100644 index 0000000..19fc4f2 --- /dev/null +++ b/ui/semesters.lp @@ -0,0 +1,72 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Semester Definition and Configuration +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Define the range of semesters based on 'n' +semester(I) :- _clinguin_const(n,N), I = 1..N. + +% Possible values for the number of semesters +values(3..8). + +% Determine the season for each semester +semester_season(I, "") :- semester(I), empty(int(m(s), s(I))). +semester_season(I, "") :- semester(I), empty(int(m(w), s(I))). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Center Section Configuration - Semester Control + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Display current number of semesters with update option + elem(semester_control_container, container, center_section). + attr(semester_control_container, order, 1). + attr(semester_control_container, flex_direction, row). + attr(semester_control_container, class, ("m-2";"bg-info";"rounded";"bg-opacity-10";"align-self-center";"justify-content-between";"w-75")). + + elem(semester_control_number_container, container, semester_control_container). + attr(semester_control_number_container, flex_direction, row). + attr(semester_control_number_container, class, ("p-2"; "m-2")). + + % Label showing current number of semesters + elem(semester_count_label, label, semester_control_number_container). + attr(semester_count_label, label, "Number of semesters: "). + attr(semester_count_label, order, 1). + attr(semester_count_label, class, ("fw-bold"; "p-2"; "m-2")). + + % Dropdown menu to select the number of semesters + elem(semester_dropdown, dropdown_menu, semester_control_number_container). + attr(semester_dropdown, order, 2). + attr(semester_dropdown, selected, N):_clinguin_const(n, N). + attr(semester_dropdown, class, ("btn-sm"; "btn-outline-dark"; "p-2"; "m-2")). + + % Dropdown options for selecting semesters + elem(semester_option(V), dropdown_menu_item, semester_dropdown) :- values(V). + attr(semester_option(V), label, V) :- values(V). + when(semester_option(V), click, call, set_constant("n", V)) :- values(V). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Semester Display + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Display list of semesters + elem(semester_display_container, container, center_section). + attr(semester_display_container, order, 2). + attr(semester_display_container, class, ("d-flex"; "flex-wrap"; "flex-row"; "justify-content-center"; "align-items-start"; "w-100")). + + % Individual semester containers + elem(semester_container(I), container, semester_display_container) :- semester(I). + attr(semester_container(I), order, I) :- semester(I). + attr(semester_container(I), class, ("border-opacity-50"; "fw-bold"; "p-3"; "m-2"; "rounded"; "border"; "border-2"; "bg-opacity-10")) :- semester(I). + attr(semester_container(I), class, ("border-warning")) :- semester(I), empty(int(m(w), s(I))). + attr(semester_container(I), class, ("border-primary")) :- semester(I), empty(int(m(s), s(I))). + attr(semester_container(I), class, ("bg-warning")) :- semester(I), empty(int(m(w), s(I))). + attr(semester_container(I), class, ("bg-primary")) :- semester(I), empty(int(m(s), s(I))). + + % Header for each semester + elem(semester_header_container(I), container, semester_container(I)) :- semester(I). + attr(semester_header_container(I), order, 1) :- semester(I). + attr(semester_header_container(I), class, ("text-dark";"fw-bold";"p-2";"m-1"; "rounded")) :- semester(I). + + % Label for semester headers + elem(semester_label(I), label, semester_header_container(I)) :- semester(I). + attr(semester_label(I), label, @concat(Season, " Semester ",I)) :- semester(I), semester_season(I, Season). + attr(semester_label(I), order, 1) :- semester(I). diff --git a/ui/subsets.lp b/ui/subsets.lp new file mode 100644 index 0000000..1919ced --- /dev/null +++ b/ui/subsets.lp @@ -0,0 +1,99 @@ + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Containers for Module Subsets + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Subsets of modules + subset(E,S) :- map(l, S, _); map(u, S, _), in(E, S). + + % Containers for subsets of modules + elem(subset_container(S), container, right_section) :- subset(E,S). + attr(subset_container(S), class, ("bg-secondary";"bg-opacity-10";"fw-bold";"p-2";"m-2";"rounded"; "col-12"; "col-sm-12"; "col-md-12"; "d-flex"; "flex-column";"p-sm-4";"p-lg-3")) :- subset(E,S). + attr(subset_container(S), flex_direction, column) :- subset(E,S). + attr(subset_container(S), order, O) :- subset(E,S),set_name(S,_,O). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Labels for Module Subsets + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Label container for subsets + elem(subset_label_container(S), container, subset_container(S)):-subset(E,S). + attr(subset_label_container(S), order, 1):-subset(E,S). + attr(subset_label_container(S), class, ("fw-bold";"pb-2";"mb-2";"rounded")):-subset(E,S). + + % Label text for subsets + elem(subset_label(S), label, subset_label_container(S)):-subset(E,S). + % attr(subset_label(S), label, @concat("Modules ", S)):-subset(E,S), S != m. + attr(subset_label(S), label, N):-subset(E,S), set_name(S,N,_). + attr(subset_label(S), order, 1):-subset(E,S). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Display Modules in Subsets + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Display modules within each subset + elem(subset_modules_container(S), container, subset_container(S)) :- subset(E,S). + attr(subset_modules_container(S), order, 2):- subset(E,S). + attr(subset_modules_container(S), class, ("d-flex"; "flex-wrap"; "gap-2")):- subset(E,S). + attr(subset_modules_container(S), flex_direction, row) :- subset(E,S). + + % Module is visibly selected if it is in a semester + module_visibly_selected(E) :- shown_module(E, I), semester(I). + + % Button for modules in a subset + elem(subset_module_button(E,S), button, subset_modules_container(S)) :- in(E,S), subset(E,S). + attr(subset_module_button(E,S), label, @concat(E,": ",EN)) :- in(E,S), subset(E,S), module_program(_, EN, E, _, _). + attr(subset_module_button(E,S), class, ("btn-sm"; "text-start"; "align-self-center"; "w-100")) :- in(E,S), subset(E,S). + attr(subset_module_button(E,S), class, "btn-secondary") :- in(E,S), subset(E,S), module_visibly_selected(E). + attr(subset_module_button(E,S), class, "btn-outline-secondary") :- in(E,S), subset(E,S), not module_visibly_selected(E). + + % Add success/danger classes based on include/exclude preferences + % attr(subset_module_button(E,S), class, "text-success") :- in(E,S), subset(E,S), user_preference(include(_),E). + % attr(subset_module_button(E,S), class, "text-danger") :- in(E,S), subset(E,S), user_preference(exclude(_),E). + + % Add icons for hard/soft inclusion and exclusion preferences + attr(subset_module_button(E,S), icon, ("fa-solid"; "fa-thumbs-up")) :- in(E,S), subset(E,S), user_preference(include(hard),E). + attr(subset_module_button(E,S), icon, ("fa-regular"; "fa-thumbs-up")) :- in(E,S), subset(E,S), user_preference(include(soft),E). + attr(subset_module_button(E,S), icon, ("fa-regular"; "fa-thumbs-down")) :- in(E,S), subset(E,S), user_preference(exclude(soft),E). + attr(subset_module_button(E,S), icon, ("fa-solid"; "fa-thumbs-down")) :- in(E,S), subset(E,S), user_preference(exclude(hard),E). + + when(subset_module_button(E,S), click, update, (module_info_modal(E), visibility, shown)) :- in(E,S), subset(E,S). + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Display Progress Bars for Credits in Each Subset + %%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + % Total credits for selected modules in each subset + subset_total_credits(S, TotalCredits) :- + subset(_, S), + TotalCredits = #sum { C, E : module_visibly_selected(E), in(E, S), map(c, E, C) }. + + % Remaining credits for each subset + remaining_credits(S, Remaining, TotalCredits) :- + map(l, S, LowerBound), + subset_total_credits(S, TotalCredits), + Remaining = LowerBound - TotalCredits. + + % Progress percentage of completed credits for each subset + progress_percentage(S, Percentage) :- + map(l, S, LowerBound), + subset_total_credits(S, TotalCredits), + LowerBound > 0, + Percentage = (TotalCredits * 100) / LowerBound. + + % Container for progress bar showing credits completed + elem(progress_bar_container(S), container, subset_container(S)) :- subset(_, S). + attr(progress_bar_container(S), order, 4) :- subset(_, S). + attr(progress_bar_container(S), class, ("pt-3"; "mt-auto")) :- subset(_, S). + + % Progress bar indicating credit completion percentage + elem(subset_progress_bar(S), progress_bar, progress_bar_container(S)) :- subset(_, S). + attr(subset_progress_bar(S), value, P) :- progress_percentage(S, P). + attr(subset_progress_bar(S), class, ("progress-bar-striped"; "progress-bar-animated"; "rounded")) :- subset(_, S). + attr(subset_progress_bar(S), out_label, @concat(Remaining, " ECTS")) :- + remaining_credits(S, Remaining, _), Remaining > 0. + attr(subset_progress_bar(S), label, @concat(TotalCredits, " ECTS")) :- + remaining_credits(S, _, TotalCredits). + attr(subset_progress_bar(S), height, 30) :- progress_percentage(S, P). + attr(subset_progress_bar(S), class, "bg-success") :- progress_percentage(S, P), P >= 100. + attr(subset_progress_bar(S), class, "bg-warning") :- progress_percentage(S, P), P >= 50, P < 100. + attr(subset_progress_bar(S), class, "bg-danger") :- progress_percentage(S, P), P < 50. diff --git a/ui/ui_main.lp b/ui/ui_main.lp new file mode 100644 index 0000000..99c15b7 --- /dev/null +++ b/ui/ui_main.lp @@ -0,0 +1,30 @@ +% Main file that includes all the UI components + +% Include semester-related logic +#include "ui/semesters.lp". + +% Include layout-related logic +#include "ui/layout.lp". + +% Include module-related logic +#include "ui/modules.lp". + +% Include subset display and progress bar logic +#include "ui/subsets.lp". + +% Include modals for module info +#include "ui/modals.lp". + +% Include the main menu bar logic +#include "ui/menu_bar.lp". + +#include "ui/exams.lp". + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Root Window Configuration +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +elem(root_window, window, root). +attr(root_window, flex_direction, column). + +%when(root_window, load, update, (module_info_modal(E), visibility, shown)) :- _clinguin_context(modal_opened,E).