Competence-Based KST (CB-KST)

CB-KST derives a knowledge structure from a skill map — the mapping from items to the skills required to solve them.

The model

Given:

  • A set of items \(Q\) (problems/questions)

  • A set of skills \(S\) (competencies)

  • A skill map \(\mu: Q \to 2^S\) (each item requires a set of skills)

  • A prerequisite relation on skills

The problem function maps a competence state \(C \subseteq S\) to the set of solvable items (an item is solvable iff all its required skills are mastered — the conjunctive model):

\[p(C) = \{q \in Q \mid \mu(q) \subseteq C\}\]

The knowledge structure is the image of all valid competence states:

\[\mathcal{K} = \{p(C) \mid C \in \mathcal{C}\}\]

Note. With a conjunctive skill map, \(\mathcal{K}\) is not guaranteed to be union-closed, so the result is a knowledge structure but not necessarily a knowledge space. Check with is_knowledge_space.

Usage

High-level API

import knowledgespaces as ks

structure = ks.structure_from_skill_map(
    skill_map={
        "q1": ["s_add"],
        "q2": ["s_add", "s_carry"],
        "q3": ["s_mul", "s_add"],
    },
    skill_prerequisites=[("s_add", "s_carry")],
)

Low-level API

from knowledgespaces import SkillMap, derive_knowledge_structure
from knowledgespaces.structures import SurmiseRelation

skill_map = SkillMap(
    items=["q1", "q2", "q3"],
    skills=["s_add", "s_carry", "s_mul"],
    mapping={
        "q1": {"s_add"},
        "q2": {"s_add", "s_carry"},
        "q3": {"s_mul", "s_add"},
    },
)

skill_rel = SurmiseRelation(
    ["s_add", "s_carry", "s_mul"],
    [("s_add", "s_carry")],
)

result = derive_knowledge_structure(skill_map, skill_rel)

print(result.competence_structure.n_states)
print(result.knowledge_structure.n_states)
print(result.knowledge_structure.is_knowledge_space)

# mapping: competence state -> induced knowledge state
for comp_state, know_state in result.mapping.items():
    print(set(comp_state), "->", set(know_state))

Skill-to-item conversion

You can also derive the item prerequisite relation from the skill map. Item \(p\) precedes \(q\) iff every skill required by \(p\) is either required by \(q\) or is a prerequisite of one:

\[\mathrm{covers}(q) = \mu(q) \,\cup\, \{s : \exists\, t \in \mu(q),\ (s, t) \in \mathord{\preceq}\} \qquad p \prec q \iff \mu(p) \subseteq \mathrm{covers}(q)\]
from knowledgespaces import skill_to_item_relation

item_rel = skill_to_item_relation(skill_map, skill_rel)
for a, b in item_rel:
    print(f"{a}{b}")

Alternative: surmise functions

When an item can be solved through different alternative prerequisite sets (the disjunctive case), use a surmise function instead — see space_from_surmise_function in structures.