NOf Requirements 2

Matching courses to requirements

One of the core responsibilities of NOf requirements is to match courses to the requirements they satisfy. This is not straight-forward in those cases where a course can match any of several requirements.

To draw on part of the Bachelor of Computer Science plan specification:

all of "CS electives" {
    3 from ^CS_340-398 + ^CS_440-489
    2 from ^CS_440-489
    1 of {
        ^CS_487
        ^CS_440-498
        ^CS_499T
    }
}

Suppose the student has CS346, CS348, CS370, CS454, CS488, and CS492.

The first requirement could be met with any three of these courses. But if the program arbitrarily chooses CS454, CS488, and CS492 to satisfy the first requirement, it won’t be able to satsify the other two.

In this case, the program “backtracks” and tries a different combination of courses for the first requirement. It then moves “forward” again to see if the second and third requirements can be met with the remaining courses.

It will eventually settle on the following assignments:

  • CS346, CS348, CS370 for the 3 of requirement.
  • CS454 and CS488 for the 2 of requirement.
  • CS492 for the 1 of requirement.

There are several things to note about this example:

  • If the program fails to satisfy a requirement, it backtracks to see if it can find a different solution for a previous requirement. It then moves forward again. It only gives up and declares a requirement can’t be satisfied if it has tried every combination.
  • CS454 and CS488 can be used to satisfy any of the three requirements, but they are not reused. Each course is used at most once (unless there is an override in place).
Note

A course is only used once, even though it might match several rules. (Unless there is an override in place.)

Reusing courses

Sometimes it is legitimate to reuse courses. Computer Science, for example, has a “breadth and depth” requirement:

all of "CS breadth & depth" {
    humanities =  ^(ARTS_|CHINA_|CLAS_|CMW_|CROAT_|DAC_|DRAMA_|DUTCH_).* 
    socialSci = ^(AFM_|ANTH_|APPLS_|ARBUS_|BET_|BUS_|COMM_|ECON_|ENBUS_).* 
    pureSci = ^(BIOL_|CHEM_|EARTH_|PHYS_|SCI_).*
    pureApplSci = pureSci + ^(ENVE_|ENVS_|ERS_|GERON_|HLTH_|KIN_).*

    all of "breadth" {
        1.0 units from "Humanities" humanities
        1.0 units from "Social Sciences" socialSci
        0.5 units from "Pure Sciences" pureSci
        0.5 units from "Pure & Applied Sciences" pureApplSci
    }

    1 of "depth" {
        2 of {  0.5 units from ^AFM_[34].* 1.0 units from ^AFM_.* }
        2 of {  0.5 units from ^ANTH_[34].* 1.0 units from ^ANTH_.* }
        2 of {  0.5 units from ^APPLS_[34].* 1.0 units from ^APPLS_.* }
        # Many more subjects omitted
    }
}

The above requirements almost capture the intent of the depth and breadth. What’s missing is that the same ANTH courses can be used to meet both the social sciences breadth requirement and the depth requirement. But as we just learned, the default behaviour is to allow each course to be used only once.

The default can be overridden by modifying the all of clause to include using all nonMathCourses in two places:

all of "CS breadth & depth" {
    ...
    all of "breadth" using all nonMathCourses {
        ...
    }

    1 of "depth" using all nonMathCourses {
        ...
    }
}

What follows using all is a list of courses that may be reused. It would often be passedCourses but might be any other set, either named or otherwise.

Efficiency

The using all clause can make the program run much more efficiently because it does not need to backtrack out of the all of requirement with the using all. If, for example, it can’t find a set of courses to meet the depth requirement, it does not need to backtrack to the breadth requirement to try different combinations there. Similarly, if a later rule is not satisfied, the program does not need to try different ways to satsify the depth rules – it won’t affect the later rules.

Limiting courses

Another use of the using clause is to limit the courses used in the NOf requirement but without saying they can be reused. For example,

all of "electives" using remaining nonMathCourses {
    ...
}

specifies that only non-math courses that have not yet been used will be considered for the sub-requirements.

This may have a very modest efficiency benefit. The real benefit is that if a sub-requirement is not satisfied, only non-math courses will be listed as possible courses to take.

Default

The default for the using clause – when it is not specified – is to use the remaining courses of whatever courses were used in the enclosing rule.

In this example, the inner NOf requirement only uses the CS courses that have not been used by the outer NOf requirements that precede it.

all of using csCourses {
    ...
    all of {
        ...
    }
}
Note

It is important to note that the course set passedCourses does not include any PD courses, WKRPT courses or COOP courses. The definitions for these courses can be found at uw/u/baseCourseDefs-1109.plan.