Models
evidencelib keeps the model explicit. The same expression can mean different
things depending on the frame.
DST
frame = Frame.dst(["A", "B", "C"])
DST uses exhaustive and mutually exclusive hypotheses. A & B is therefore
empty, and frame.elements() generates the classical power set.
Use DST when: exactly one hypothesis can be true, for example one label selected from a known set of classes.
Common workflows use dempster(), yager(), pcr5(), pcr6(), and
pignistic().
Free DSmT
frame = Frame.dsmt(["A", "B", "C"])
Free DSmT keeps hypotheses exhaustive but allows overlap. A & B can be a real
state, and frame.elements() generates the hyper-power set.
Use free DSmT when: categories are vague, overlapping, or not safely separable.
In this model, A, B, and A & B can all carry distinct mass. dsmc() keeps
mass on intersections instead of treating them as conflict.
Hybrid DSmT
frame = Frame.hybrid(["A", "B", "C"], exclusive=True, empty=["C"])
Hybrid DSmT adds explicit constraints. Some intersections can be impossible, or new knowledge can make a hypothesis empty.
Examples:
Frame.hybrid(["A", "B"], exclusive=True)
Frame.hybrid(["A", "B", "C"], empty=["A & B"])
Frame.hybrid(["A", "B", "C"], exclusive=[("A", "B")])
Use hybrid DSmT when: most hypotheses can overlap, but some combinations are impossible or have become impossible.
Use dsmh() when conflict should be redistributed according to model
constraints instead of normalized away.
Static and dynamic constraints
For a static model, create sources directly on the constrained frame when they assign no mass to impossible propositions. For constraints discovered after the sources were elicited, keep the source masses on their original frame and pass the target model explicitly:
source = Frame.dsmt(["A", "B", "C"])
A, B, C = source.symbols()
m1 = source.mass({A & B: 1.0})
m2 = source.mass({A & B: 1.0})
target = Frame.hybrid(["A", "B", "C"], empty=["A&B"])
result = m1.dsmh(m2, model=target)
assert result.to_dict() == {"A|B": 1.0}
The original A&B expression is essential here: the S2 term uses
u(A&B) = A|B. Creating the masses on target would discard that provenance.
Target projection may add constraints, but it cannot make Venn regions possible
that were absent from the source model; constraint relaxation requires a new
source model and re-elicited/reconstructed masses.
Element growth
DSmT proposition spaces grow quickly:
Frame.dsmt(["A", "B"]).elements()has 5 elements.Frame.dsmt(["A", "B", "C"]).elements()has 19 elements.Frame.dsmt(["A", "B", "C", "D"]).elements()has 167 elements.A five-atom free model already has 7,580 elements.
Frame.elements() has a safety limit. Pass max_count=None only when you
really want the full closure.