Violation generation reference¶
Everything below is in shifty.experimental.vio.
Nodes and triples are N-Triples terms, such as
<http://ex/s1>and"degC".Arguments that take IRIs accept them bare or in angle brackets.
Universe¶
vio.Universe(data_graph, shacl_graph, *, infer=True,
include_external_foci=False, canonicalize_blank_nodes=True,
graph_mode="union", on_unsupported="error", base=None,
limits=None)
Every way to break a conforming graph, as a sequence of Injection
objects. Creating one compiles the shapes and validates the graph. Injections
are found later, when you draw or list.
Parameter |
Meaning |
|---|---|
|
The reference graph and the shapes, in any form |
|
Run the shapes’ SHACL-AF rules on every check. Only asserted
triples are edited, and an edit the rules would undo is dropped.
|
|
Also break nodes with no outgoing triples, such as vocabulary terms the shapes describe. |
|
Rename blank nodes the same way every run, so draws reproduce. Turn off to keep the input’s names. |
|
As in |
|
An |
Member |
Meaning |
|---|---|
|
Find every injection and keep them in memory. Later draws reuse them. |
|
The injections that break |
|
The same injections, drawn with these weights. Keys are predicate IRIs and operation kinds; missing keys weigh 1. An injection weighs the geometric mean of its predicates’ weights times the geometric mean of its kinds’ weights. |
|
A |
|
One |
|
The |
|
The original graph as sorted N-Triples. It holds only asserted triples. |
|
The weights of this view. |
Injection and Operation¶
An Injection is one way to break the graph: operations that together
make one node fail one shape.
Attribute |
Meaning |
|---|---|
|
The node it breaks. |
|
The shape statement it breaks, and its IRI if it has one. |
|
Its |
|
Its edits, as sets of triples and as a |
|
The predicates it edits, and its operations’ kinds. |
|
Its edits as sorted |
An Operation has kind, node, polarity, deletes,
adds, and detail, a description for people. polarity is
"violate", or "satisfy" under sh:not, where the edit makes the
negated shape hold.
Kind |
Edit |
|---|---|
|
Delete a triple a constraint needs, such as a sensor’s only label
under |
|
Replace a value with one that fails, such as |
|
Add a value, such as a second label under |
|
Add a predicate a |
Case¶
Member |
Meaning |
|---|---|
|
The draw that made it. |
|
The injections, in the order they were admitted. At most |
|
Every failing |
|
The edits that broke the graph, and their inverse, as
|
|
The broken graph, as an |
|
The broken graph with |
|
|
|
The |
|
Write |
ExpansionLimits¶
Bounds on the search for injections. Each caps one way it branches, so a large graph does not give an unbounded universe.
Field |
Default |
Caps |
|---|---|---|
|
24 |
Alternatives kept at any one choice. |
|
6 |
Values sampled per count or universal constraint. |
|
3 |
Replacement or new terms tried per value. |
|
12 |
Joint choices when several values must change together. |
|
12 |
Nesting through |
|
64 |
Injections per node and shape. |
|
200,000 |
Injections in total. |
generate¶
vio.generate(data_graph, shacl_graph, out, *, budgets=(5,), cases=10,
seed=0, jobs=1, shape=None, predicate=None, focus=None,
predicates=None, kinds=None, infer=True)
Draws cases cases for each k in budgets, writes them under
out, and returns the contents of suite.json.
Seeds run
seed,seed + 1, and so on.shape,predicate, andfocusfilter, as inwhere.predicatesandkindsweight, as inweighted.inferis as inUniverse.jobssplits the cases across worker processes. The suite is the same for any value.
Output files¶
out/
reference.nt the reference graph
suite.json the summary
k05/case-003/ k = 5, the fourth case (seed + 3)
graph.nt the broken graph
repair.ru the repair, as a SPARQL update
case.json the manifest
suite.json holds:
baseline_failures: how many pairs already failed.operation_kinds: how many operations of each kind the suite injected.cases: one row per case, withpath,k,seed,injected, andfailures.
case.json holds:
kandseed.deltaandrepair.injections, each withfocus,statement,shape,predicates,operations, andkey.failures, each withfocus,statement,shape, and the indices of itsinjections.
Command line¶
python -m shifty.experimental.vio --data DATA --shapes SHAPES --out OUT [options]
Option |
Meaning |
|---|---|
|
The reference graph and the shapes, as paths or URLs. Required. |
|
The output directory. Required. |
|
Injections per case. Repeat for several budgets. Default 5. |
|
Cases per budget. Default 10. |
|
The first case’s seed; later cases count up. Default 0. |
|
Break only this shape, edit only this predicate. Both repeat. |
|
A JSON file mapping predicate IRIs to weights. |
|
A JSON file mapping operation kinds to weights. |
|
Run the shapes’ rules on every validation, or not. On by default. |
|
Worker processes. Default 1. |
It exits with status 1 on an error. It warns when the original graph already has failures.
Rust¶
shifty_experimental::vio exports Universe, Options,
Weights, ExpansionLimits, Injection, Operation,
OperationKind, Polarity, Case, CaseFailure, and
Triple. The Python module wraps them, and the names match, with two
exceptions:
filtertakes a closure, in place ofwhere.weightedtakes aWeights.
use shifty_experimental::vio::{Options, Universe};
let shapes = shifty_parse::load_turtle(shapes_ttl, None)?;
let data = shifty_parse::load_turtle(data_ttl, None)?.graph;
let universe = Universe::new(shapes, data, Options::default())?;
let zones = universe.filter(|e| e.shape.as_deref() == Some(ZONE));
let requests: Vec<(usize, u64)> = (0..10).map(|seed| (5, seed)).collect();
for case in zones.draws(&requests)? {
let graph = case.graph_ntriples();
let repair = case.repair(); // a shifty_repair::GraphDelta
}
Limitations¶
sh:equals,sh:disjoint,sh:lessThan, SPARQL constraints, andsh:xoneare not broken yet.New values are taken from the graph, derived from the constraint (a string one character too short), or minted as fresh IRIs. They are not realistic names.
A property path is broken along its shortest route only.
A value that only an inferred triple supports cannot be cut. That would take editing the rule’s premises, which the search does not trace.
When two injections break the same property, the check confirms that the property fails, not that both injections are needed.