pre { var threshold = 3; } rule Movie transform c : movies!Movie to t : movies2!Movie { t.title = c.title; t.rating = c.rating; t.year = c.year; t.type = c.type; t.persons ::= c.persons; //<- not needed as Movie.persons is an opposite of Person.movies } rule Actor transform a : movies!Actor to b : movies2!Actor { b.name = a.name; //b.movies ::= a.movies; //<- not needed as Movie.persons is an opposite of Person.movies if (a.movies.size() >= threshold) { for (t in a.coactors()) { if (a.name.compareTo(t.name) < 0 and t.movies.size() >= threshold and a.areCouple(t)){ // Changed the order of the two operands var couple : new movies2!Couple; couple.p1 ::= a; couple.p2 ::= t; } } } } rule Actress transform a : movies!Actress to b : movies2!Actress { b.name = a.name; //b.movies ::= a.movies; //<- not needed as Movie.persons is an opposite of Person.movies if (a.movies.size() >= threshold) { for (t in a.coactors()) { if (a.name.compareTo(t.name) < 0 and t.movies.size() >= threshold and a.areCouple(t)) { // Changed the order of the two operands var couple : new movies2!Couple; couple.p1 ::= a; couple.p2 ::= t; } } } } operation movies!Person coactors() : Set(movies!Person) { var coactors : Set; for (m in self.movies) { coactors.addAll(m.persons); } return coactors; } operation movies!Person areCouple(p:movies!Person) : Boolean { return self.movies.excludingAll(p.movies).size() <= self.movies.size() - threshold; }