---
title: "CDSS"
author: "Cord Hockemeyer"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{CDSS}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(Rgraphviz)
library(kstMatrix)
library(CDSS)
library(CbKST)
```

# Content
- [Introduction](#introduction)
  - [Skill assignment data files](#skill-assignment-data-files)
- [Workflow](#workflow)
  - [Deriving skill structures](#deriving-skill-structures)
  - [Deriving LO structures](#deriving-lo-structures)
- [Limitations of the CDSS approach](#limitations-of-the-cdss-approach)


# Introduction
The `CDSS` package (course dependent skill structures) provides a way to quickly develop a rough competence structure 
for an existing course. The basic idea is to identify, for each lesson of the course, the skills taught by that lesson 
and required for understanding that lessons, respectively. The interesting point is that only the _direct_ prerequisite 
skills have to be specified.

From this skill assignment, attribution functions (and possibly also attribution relations) can be derived on the level of both,
skills and learning objects. These are then the basis for deriving and further processing skills spaces and learning object 
spaces using functions, e.g., of the `kstMatrix` package. On the other side, it is also possible to derive a skill map through
the `cdss_sa2mu()` function which grounds a connection to the `CbKST` package.

The resulting structures may well need further, manual refinement, e.g. with respect to falsely equivalent skills 
**(see [below](#sec:dealing-with-equivalence-classes)).**

## Skill assignment data files
Information on the assignment of skills to learning objects can be specified in the three most standard spreadsheet
file formats (CSV, ODS, and XLSX). For ODS and XLSX files, two sheets are expected specifying assignment of taught and required skills respectively. For the CSV case, two distinct files are expected because CSV does not support for multi-sheet files.

Each sheet (or CSV each file) contains a table with two columns, learning object id and skill id. For each skill assigned to a learning object, there is a separate row. The table must contain a header row.

### Example
The CDSS package provides example data files in the `extdata` directory.

```{r readfile}
fpath <- system.file("extdata", package="CDSS")
sa <- cdss_read_skill_assignment(paste0(fpath, "/SkillAssignment.ods"))
sa
```

By default, skill assignments which do not hold certain properties, are rejected. This behavior can be changed by setting the
optional parameter `warnonly` to `TRUE`.

```{r erroneous}
cdss_read_skill_assignment_ods(paste0(fpath, "/ErroneousSkillAssignment.ods"), warnonly=TRUE)
```

# Workflow
Figure 1 shows an overall view of the possible workflow(s) within the `CDSS` package including the interfacing points to the 
`kstMatrix` and `CbKST` packages.

```{r workflow, fig.cap = 'Figure 1: CDSS workflow', echo = FALSE, fig.align = 'center', cache=TRUE, out.width='90%'}
knitr::include_graphics("Flowchart.png")
```

## Deriving skill structures
There are two ways to derive the skill structure from the skill assignment, through an attribution function or through a skill 
(multi) map. Both ways lead to the same skill structure. Further processing then has to be done using functions from the `kstMatrix` and `CbKST`packages.

### Example

``` {r af, fig.cap='FIgure 2: Derived skill space', fig.align='center', cache=TRUE, out.width='60%'}
af <- cdss_skill_sa2af(sa) # Attribution function
af
plot(kmspace(kmbasis(kmclosure(af))))
```
``` {r mu, fig.cap='FIgure 3: Dweriving a skill space through the skill multi map', fig.align='center', cache=TRUE, out.width='60%'}
mu <- cdss_sa2mu(sa) # Skill multi map
mu
plot(kmspace(kmbasis(cbkst_competencestructure(mu))))
```

## Deriving LO structures
For LO structures, things are similar to but still slightly different from skill structures. Again, we have two ways to derive
an LO space but the meaning of the LO states is different and thus are the spaces. The straightforward definition of an LO state 
would be the set of LOs the learner has visited. The respective LO space is achieved using the attribution function way. For a 
skill (multi) map, however, the LO state of a learner is the set of LOs whose (required **and** taught) skills this learner has.
One can also have a look at the possible learning paths through the LO space.

### Example

``` {r laf, fig.cap='FIgure 4: LO space derived through the attribution function', fig.align='center', cache=TRUE, out.width='90%'}
laf <- cdss_lo_sa2af(sa) # Attribution function
laf
lospc <- kmspace(kmbasis(kmclosure(laf)))
plot(lospc)
lp <- kmlearningpaths(lospc)
length(lp)
lp[[1]]
lp[[2]]
```

``` {r lmu, fig.cap='FIgure 5: LO space derived through the skill multi map', fig.align='center', cache=TRUE, out.width='90%'}
plot(kmspace(kmbasis(cbkst_performancestructure(mu)))) # Skill multi map
```
The latter LO space has 37 states while the former one has 42 states.

# Limitations of the CDSS approach
## Course-dependence of the obtained skill structure
CDSS stands for *course-dependent skill structures*. This means that a different course teaching the same set of skills will
most probably lead to a different skill structure. That is, we do not give a perfect solution but rather a starting point 
for further development of the structure.

## Possibly falsely equivalent skills
It may often occur that one learning object teaches multiple skills. If there are no other learning objects teaching these skills
in different combinations, they will be deemed as equivalent although this may just be a course-dependent artifact. In this case,
a refinement o the obrtained skill space may well be reasonable. The functions of the `kstMatrix` package offer the right tools 
for this. In our example space, e.g., the skills *f* and *g* are equivalent. We remedy this by determining the intersection of 
this space with a second one which makes *f* a prerequisite of *g*.
``` {r Refinement, fig.cap='FIgure 6: Refining a basis', fig.align='center', cache=TRUE, out.width='40%'}
sf <- kmclosure(af) # Surmise function
bas <- kmbasis(sf)
plot(kmbasis(bas))
extbas <- matrix(c(1,0,1,1), nrow=2, byrow=TRUE)
colnames(extbas) <- c("f", "g")
class(extbas) <- unique(c("kmbasis", "kmfamset", class(extbas)))
extbas
newbas <-kmrefine(bas, extbas)
newbas
class(newbas)
```

``` {r refined, fig.cap='FIgure 7: Refined basis', fig.align='center', cache=TRUE, out.width='40%'}
plot(newbas)
```

