kibi-core 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/checks.pl +277 -7
- package/src/kb.pl +52 -8
package/package.json
CHANGED
package/src/checks.pl
CHANGED
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
check_deprecated_adrs/1, % Returns list of deprecated ADR violations
|
|
16
16
|
check_domain_contradictions/1, % Returns list of contradiction violations
|
|
17
17
|
check_strict_fact_shape/1, % Returns list of malformed strict fact violations
|
|
18
|
-
|
|
18
|
+
check_strict_req_fact_pairing/1,% Returns list of malformed strict req/fact pairing violations
|
|
19
|
+
check_strict_readiness/1, % Returns list of strict readiness audit violations
|
|
20
|
+
run_checks_json/0, % Entry point for JSON output
|
|
21
|
+
violation_id_text/2 % Extract text from entity ID term (exported for testing)
|
|
19
22
|
]).
|
|
20
23
|
|
|
21
24
|
:- use_module(library(http/json)).
|
|
@@ -47,6 +50,8 @@ check_all(ViolationsDict) :-
|
|
|
47
50
|
check_deprecated_adrs(DeprecatedADRs),
|
|
48
51
|
check_domain_contradictions(Contradictions),
|
|
49
52
|
check_strict_fact_shape(StrictFactShape),
|
|
53
|
+
check_strict_req_fact_pairing(StrictReqFactPairing),
|
|
54
|
+
check_strict_readiness(StrictReadiness),
|
|
50
55
|
ViolationsDict = _{
|
|
51
56
|
must_priority_coverage: MustPriority,
|
|
52
57
|
symbol_coverage: SymbolCoverage,
|
|
@@ -56,7 +61,9 @@ check_all(ViolationsDict) :-
|
|
|
56
61
|
required_fields: RequiredFields,
|
|
57
62
|
deprecated_adr_no_successor: DeprecatedADRs,
|
|
58
63
|
domain_contradictions: Contradictions,
|
|
59
|
-
strict_fact_shape: StrictFactShape
|
|
64
|
+
strict_fact_shape: StrictFactShape,
|
|
65
|
+
strict_req_fact_pairing: StrictReqFactPairing,
|
|
66
|
+
strict_readiness: StrictReadiness
|
|
60
67
|
}.
|
|
61
68
|
|
|
62
69
|
%% check_must_priority_coverage(-Violations)
|
|
@@ -412,7 +419,8 @@ property_value_shape_error(Props, "Property value fact has multiple value fields
|
|
|
412
419
|
length(Fields, Count),
|
|
413
420
|
Count > 1.
|
|
414
421
|
property_value_shape_error(Props, "Property value fact value_type does not match value field") :-
|
|
415
|
-
memberchk(value_type=
|
|
422
|
+
memberchk(value_type=RawVT, Props),
|
|
423
|
+
normalize_term_atom(RawVT, VT),
|
|
416
424
|
\+ value_type_matches_field(VT, Props).
|
|
417
425
|
|
|
418
426
|
% is_value_field(+Field)
|
|
@@ -440,11 +448,255 @@ check_domain_contradictions(Violations) :-
|
|
|
440
448
|
),
|
|
441
449
|
( contradicting_reqs(ReqA, ReqB, Reason),
|
|
442
450
|
format(string(EntityId), "~w/~w", [ReqA, ReqB]),
|
|
443
|
-
Description
|
|
451
|
+
format(string(Description), "~w [strict-readiness: contradiction-ready]", [Reason])
|
|
444
452
|
),
|
|
445
453
|
Violations
|
|
446
454
|
).
|
|
447
455
|
|
|
456
|
+
%% check_strict_req_fact_pairing(-Violations)
|
|
457
|
+
% Finds current requirements attempting strict-lane modeling with incomplete
|
|
458
|
+
% subject/property pairing or wrong-lane fact targets.
|
|
459
|
+
check_strict_req_fact_pairing(Violations) :-
|
|
460
|
+
findall(
|
|
461
|
+
Violation,
|
|
462
|
+
strict_req_fact_pairing_violation(Violation),
|
|
463
|
+
Violations0
|
|
464
|
+
),
|
|
465
|
+
sort(Violations0, Violations).
|
|
466
|
+
|
|
467
|
+
strict_req_fact_pairing_violation(violation(
|
|
468
|
+
'strict-req-fact-pairing',
|
|
469
|
+
ReqId,
|
|
470
|
+
Description,
|
|
471
|
+
Suggestion,
|
|
472
|
+
Source
|
|
473
|
+
)) :-
|
|
474
|
+
strict_req_fact_pairing_issue(ReqId, Description, Suggestion),
|
|
475
|
+
violation_source(ReqId, req, Source).
|
|
476
|
+
|
|
477
|
+
strict_req_fact_pairing_issue(
|
|
478
|
+
ReqId,
|
|
479
|
+
Description,
|
|
480
|
+
"Add a property_value fact via requires_property for the same subject_key"
|
|
481
|
+
) :-
|
|
482
|
+
kb:current_req(ReqId),
|
|
483
|
+
kb_relationship(constrains, ReqId, SubjectFactId),
|
|
484
|
+
strict_req_fact_pairing_fact_kind(SubjectFactId, subject),
|
|
485
|
+
kb:fact_subject_key(SubjectFactId, SubjectKey),
|
|
486
|
+
\+ kb:effective_req_property_fact(
|
|
487
|
+
ReqId,
|
|
488
|
+
SubjectKey,
|
|
489
|
+
_PropertyFactId,
|
|
490
|
+
_PropertyKey,
|
|
491
|
+
_Operator,
|
|
492
|
+
_ValueType,
|
|
493
|
+
_Value,
|
|
494
|
+
_Unit,
|
|
495
|
+
_Scope,
|
|
496
|
+
_Polarity,
|
|
497
|
+
_ValidFrom,
|
|
498
|
+
_ValidTo
|
|
499
|
+
),
|
|
500
|
+
format(
|
|
501
|
+
string(Description),
|
|
502
|
+
"Requirement constrains ~w (~w) but has no matching strict requires_property fact",
|
|
503
|
+
[SubjectFactId, SubjectKey]
|
|
504
|
+
).
|
|
505
|
+
|
|
506
|
+
strict_req_fact_pairing_issue(
|
|
507
|
+
ReqId,
|
|
508
|
+
Description,
|
|
509
|
+
"Add a subject fact via constrains for the same subject_key or remove the mismatched requires_property link"
|
|
510
|
+
) :-
|
|
511
|
+
kb:current_req(ReqId),
|
|
512
|
+
kb_relationship(requires_property, ReqId, PropertyFactId),
|
|
513
|
+
strict_req_fact_pairing_fact_kind(PropertyFactId, property_value),
|
|
514
|
+
kb:fact_property_tuple(
|
|
515
|
+
PropertyFactId,
|
|
516
|
+
SubjectKey,
|
|
517
|
+
_PropertyKey,
|
|
518
|
+
_Operator,
|
|
519
|
+
_ValueType,
|
|
520
|
+
_Value,
|
|
521
|
+
_Unit,
|
|
522
|
+
_Scope,
|
|
523
|
+
_Polarity
|
|
524
|
+
),
|
|
525
|
+
\+ kb:effective_req_property_fact(
|
|
526
|
+
ReqId,
|
|
527
|
+
SubjectKey,
|
|
528
|
+
PropertyFactId,
|
|
529
|
+
_MatchedPropertyKey,
|
|
530
|
+
_MatchedOperator,
|
|
531
|
+
_MatchedValueType,
|
|
532
|
+
_MatchedValue,
|
|
533
|
+
_MatchedUnit,
|
|
534
|
+
_MatchedScope,
|
|
535
|
+
_MatchedPolarity,
|
|
536
|
+
_MatchedValidFrom,
|
|
537
|
+
_MatchedValidTo
|
|
538
|
+
),
|
|
539
|
+
format(
|
|
540
|
+
string(Description),
|
|
541
|
+
"Requirement requires_property ~w (~w) but has no matching strict subject fact via constrains",
|
|
542
|
+
[PropertyFactId, SubjectKey]
|
|
543
|
+
).
|
|
544
|
+
|
|
545
|
+
strict_req_fact_pairing_issue(
|
|
546
|
+
ReqId,
|
|
547
|
+
Description,
|
|
548
|
+
"Use a subject fact with constrains for contradiction-safe semantics; keep non-subject facts out of strict pairing"
|
|
549
|
+
) :-
|
|
550
|
+
kb:current_req(ReqId),
|
|
551
|
+
kb_relationship(constrains, ReqId, FactId),
|
|
552
|
+
strict_req_fact_pairing_fact_kind(FactId, Kind),
|
|
553
|
+
Kind \= subject,
|
|
554
|
+
strict_req_fact_pairing_kind_label(Kind, KindLabel),
|
|
555
|
+
format(
|
|
556
|
+
string(Description),
|
|
557
|
+
"Requirement links ~w via constrains using ~w; contradiction-safe constrains links must target subject facts",
|
|
558
|
+
[FactId, KindLabel]
|
|
559
|
+
).
|
|
560
|
+
|
|
561
|
+
strict_req_fact_pairing_issue(
|
|
562
|
+
ReqId,
|
|
563
|
+
Description,
|
|
564
|
+
"Use a property_value fact with requires_property for contradiction-safe semantics; keep non-property facts out of strict pairing"
|
|
565
|
+
) :-
|
|
566
|
+
kb:current_req(ReqId),
|
|
567
|
+
kb_relationship(requires_property, ReqId, FactId),
|
|
568
|
+
strict_req_fact_pairing_fact_kind(FactId, Kind),
|
|
569
|
+
Kind \= property_value,
|
|
570
|
+
strict_req_fact_pairing_kind_label(Kind, KindLabel),
|
|
571
|
+
format(
|
|
572
|
+
string(Description),
|
|
573
|
+
"Requirement links ~w via requires_property using ~w; contradiction-safe requires_property links must target property_value facts",
|
|
574
|
+
[FactId, KindLabel]
|
|
575
|
+
).
|
|
576
|
+
|
|
577
|
+
strict_req_fact_pairing_fact_kind(FactId, Kind) :-
|
|
578
|
+
kb_entity(FactId, fact, Props),
|
|
579
|
+
( memberchk(fact_kind=RawKind, Props)
|
|
580
|
+
-> normalize_term_atom(RawKind, Kind)
|
|
581
|
+
; Kind = legacy
|
|
582
|
+
).
|
|
583
|
+
|
|
584
|
+
strict_req_fact_pairing_kind_label(legacy, "a legacy fact without fact_kind").
|
|
585
|
+
strict_req_fact_pairing_kind_label(Kind, Label) :-
|
|
586
|
+
format(string(Label), "a fact_kind=~w fact", [Kind]).
|
|
587
|
+
|
|
588
|
+
%% check_strict_readiness(-Violations)
|
|
589
|
+
% Reports current strict-readiness levels for requirements that are still not
|
|
590
|
+
% contradiction-ready. Legacy and prose-only requirements remain audit-only and
|
|
591
|
+
% are intentionally not treated as contradictions.
|
|
592
|
+
check_strict_readiness(Violations) :-
|
|
593
|
+
findall(
|
|
594
|
+
Violation,
|
|
595
|
+
strict_readiness_violation(Violation),
|
|
596
|
+
Violations0
|
|
597
|
+
),
|
|
598
|
+
sort(Violations0, Violations).
|
|
599
|
+
|
|
600
|
+
strict_readiness_violation(violation(
|
|
601
|
+
'strict-readiness',
|
|
602
|
+
ReqId,
|
|
603
|
+
Description,
|
|
604
|
+
Suggestion,
|
|
605
|
+
Source
|
|
606
|
+
)) :-
|
|
607
|
+
strict_readiness_issue(ReqId, Description, Suggestion),
|
|
608
|
+
violation_source(ReqId, req, Source).
|
|
609
|
+
|
|
610
|
+
strict_readiness_issue(
|
|
611
|
+
ReqId,
|
|
612
|
+
"Strict readiness: not-ready (prose-only). Requirement has no fact links, so contradiction checks skip it.",
|
|
613
|
+
"Add a subject fact via constrains and a property_value fact via requires_property to model contradiction-safe semantics"
|
|
614
|
+
) :-
|
|
615
|
+
kb_entity(ReqId, req, _),
|
|
616
|
+
strict_readiness_level(ReqId, prose_only).
|
|
617
|
+
|
|
618
|
+
strict_readiness_issue(
|
|
619
|
+
ReqId,
|
|
620
|
+
"Strict readiness: not-ready (traceable). Requirement is linked to facts only through legacy or non-strict links, so contradiction checks skip it.",
|
|
621
|
+
"Replace prose or legacy fact links with a subject fact via constrains and a property_value fact via requires_property"
|
|
622
|
+
) :-
|
|
623
|
+
kb_entity(ReqId, req, _),
|
|
624
|
+
strict_readiness_level(ReqId, traceable).
|
|
625
|
+
|
|
626
|
+
strict_readiness_issue(
|
|
627
|
+
ReqId,
|
|
628
|
+
Description,
|
|
629
|
+
"Add a matching property_value fact via requires_property for the same subject_key"
|
|
630
|
+
) :-
|
|
631
|
+
kb_entity(ReqId, req, _),
|
|
632
|
+
strict_readiness_level(ReqId, has_subject),
|
|
633
|
+
strict_readiness_primary_subject(ReqId, SubjectFactId, SubjectKey),
|
|
634
|
+
format(
|
|
635
|
+
string(Description),
|
|
636
|
+
"Strict readiness: not-ready (has-subject). Requirement constrains ~w (~w) but has no matching strict requires_property fact, so contradiction checks skip it.",
|
|
637
|
+
[SubjectFactId, SubjectKey]
|
|
638
|
+
).
|
|
639
|
+
|
|
640
|
+
strict_readiness_issue(
|
|
641
|
+
ReqId,
|
|
642
|
+
"Strict readiness: not-ready (strict-ready). Requirement has strict subject and property facts but no contradiction-ready matched pair, so contradiction checks still skip it.",
|
|
643
|
+
"Align constrains and requires_property on the same subject_key, and keep the requirement current if it should participate in contradiction checks"
|
|
644
|
+
) :-
|
|
645
|
+
kb_entity(ReqId, req, _),
|
|
646
|
+
strict_readiness_level(ReqId, strict_ready).
|
|
647
|
+
|
|
648
|
+
strict_readiness_level(ReqId, contradiction_ready) :-
|
|
649
|
+
kb:current_req(ReqId),
|
|
650
|
+
kb:effective_req_property_fact(
|
|
651
|
+
ReqId,
|
|
652
|
+
_SubjectKey,
|
|
653
|
+
_FactId,
|
|
654
|
+
_PropertyKey,
|
|
655
|
+
_Operator,
|
|
656
|
+
_ValueType,
|
|
657
|
+
_Value,
|
|
658
|
+
_Unit,
|
|
659
|
+
_Scope,
|
|
660
|
+
_Polarity,
|
|
661
|
+
_ValidFrom,
|
|
662
|
+
_ValidTo
|
|
663
|
+
),
|
|
664
|
+
!.
|
|
665
|
+
strict_readiness_level(ReqId, strict_ready) :-
|
|
666
|
+
strict_readiness_has_strict_subject(ReqId),
|
|
667
|
+
strict_readiness_has_strict_property(ReqId),
|
|
668
|
+
!.
|
|
669
|
+
strict_readiness_level(ReqId, has_subject) :-
|
|
670
|
+
strict_readiness_has_strict_subject(ReqId),
|
|
671
|
+
!.
|
|
672
|
+
strict_readiness_level(ReqId, traceable) :-
|
|
673
|
+
strict_readiness_has_fact_link(ReqId),
|
|
674
|
+
!.
|
|
675
|
+
strict_readiness_level(_ReqId, prose_only).
|
|
676
|
+
|
|
677
|
+
strict_readiness_has_fact_link(ReqId) :-
|
|
678
|
+
kb_relationship(constrains, ReqId, FactId),
|
|
679
|
+
kb_entity(FactId, fact, _),
|
|
680
|
+
!.
|
|
681
|
+
strict_readiness_has_fact_link(ReqId) :-
|
|
682
|
+
kb_relationship(requires_property, ReqId, FactId),
|
|
683
|
+
kb_entity(FactId, fact, _),
|
|
684
|
+
!.
|
|
685
|
+
|
|
686
|
+
strict_readiness_has_strict_subject(ReqId) :-
|
|
687
|
+
strict_readiness_primary_subject(ReqId, _FactId, _SubjectKey),
|
|
688
|
+
!.
|
|
689
|
+
|
|
690
|
+
strict_readiness_primary_subject(ReqId, FactId, SubjectKey) :-
|
|
691
|
+
kb_relationship(constrains, ReqId, FactId),
|
|
692
|
+
strict_req_fact_pairing_fact_kind(FactId, subject),
|
|
693
|
+
kb:fact_subject_key(FactId, SubjectKey).
|
|
694
|
+
|
|
695
|
+
strict_readiness_has_strict_property(ReqId) :-
|
|
696
|
+
kb_relationship(requires_property, ReqId, FactId),
|
|
697
|
+
strict_req_fact_pairing_fact_kind(FactId, property_value),
|
|
698
|
+
!.
|
|
699
|
+
|
|
448
700
|
%% run_checks_json
|
|
449
701
|
% Entry point for JSON output. Prints all violations as JSON to stdout.
|
|
450
702
|
run_checks_json :-
|
|
@@ -492,6 +744,8 @@ check_all_with_options(ViolationsDict, RequireAdr) :-
|
|
|
492
744
|
check_deprecated_adrs(DeprecatedADRs),
|
|
493
745
|
check_domain_contradictions(Contradictions),
|
|
494
746
|
check_strict_fact_shape(StrictFactShape),
|
|
747
|
+
check_strict_req_fact_pairing(StrictReqFactPairing),
|
|
748
|
+
check_strict_readiness(StrictReadiness),
|
|
495
749
|
ViolationsDict = _{
|
|
496
750
|
must_priority_coverage: MustPriority,
|
|
497
751
|
symbol_coverage: SymbolCoverage,
|
|
@@ -501,7 +755,9 @@ check_all_with_options(ViolationsDict, RequireAdr) :-
|
|
|
501
755
|
required_fields: RequiredFields,
|
|
502
756
|
deprecated_adr_no_successor: DeprecatedADRs,
|
|
503
757
|
domain_contradictions: Contradictions,
|
|
504
|
-
strict_fact_shape: StrictFactShape
|
|
758
|
+
strict_fact_shape: StrictFactShape,
|
|
759
|
+
strict_req_fact_pairing: StrictReqFactPairing,
|
|
760
|
+
strict_readiness: StrictReadiness
|
|
505
761
|
}.
|
|
506
762
|
|
|
507
763
|
%% violations_dict_to_json(+ViolationsDict, -JsonDict)
|
|
@@ -552,8 +808,22 @@ violation_text(Val, Text) :-
|
|
|
552
808
|
term_string(Val, Text).
|
|
553
809
|
|
|
554
810
|
violation_id_text(Val, Text) :-
|
|
555
|
-
|
|
556
|
-
|
|
811
|
+
nonvar(Val),
|
|
812
|
+
Val =.. ['^^', Inner, _Type],
|
|
813
|
+
!,
|
|
814
|
+
violation_id_text(Inner, Text).
|
|
815
|
+
violation_id_text(literal(type(_, Val)), Text) :-
|
|
816
|
+
!,
|
|
817
|
+
violation_id_text(Val, Text).
|
|
818
|
+
violation_id_text(Val, Val) :-
|
|
819
|
+
string(Val),
|
|
820
|
+
!.
|
|
821
|
+
violation_id_text(Val, Text) :-
|
|
822
|
+
atom(Val),
|
|
823
|
+
!,
|
|
824
|
+
atom_string(Val, Text).
|
|
825
|
+
violation_id_text(Val, Text) :-
|
|
826
|
+
term_string(Val, Text).
|
|
557
827
|
|
|
558
828
|
violation_source(EntityId, Type, Source) :-
|
|
559
829
|
( kb_entity(EntityId, Type, Props),
|
package/src/kb.pl
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
with_kb_mutex/1,
|
|
8
8
|
kb_assert_entity/2,
|
|
9
9
|
kb_assert_entity_no_audit/2,
|
|
10
|
-
kb_log_entity_upsert/
|
|
10
|
+
kb_log_entity_upsert/3,
|
|
11
11
|
kb_retract_entity/1,
|
|
12
|
+
kb_retract_entity/3,
|
|
12
13
|
kb_entity/3,
|
|
13
14
|
kb_entities_by_source/2,
|
|
14
15
|
kb_assert_relationship/4,
|
|
@@ -254,8 +255,13 @@ load_kb_pl_files(Directory) :-
|
|
|
254
255
|
% Assert an entity into the KB with audit logging.
|
|
255
256
|
% Properties is a list of Key=Value pairs.
|
|
256
257
|
kb_assert_entity(Type, Props) :-
|
|
258
|
+
memberchk(id=Id, Props),
|
|
259
|
+
( once(kb_entity(Id, _, _))
|
|
260
|
+
-> ChangeKind = updated
|
|
261
|
+
; ChangeKind = created
|
|
262
|
+
),
|
|
257
263
|
kb_assert_entity_no_audit(Type, Props),
|
|
258
|
-
kb_log_entity_upsert(Type, Props).
|
|
264
|
+
kb_log_entity_upsert(ChangeKind, Type, Props).
|
|
259
265
|
|
|
260
266
|
%% kb_assert_entity_no_audit(+Type, +Properties)
|
|
261
267
|
% Assert an entity RDF payload without recording audit side effects.
|
|
@@ -284,19 +290,30 @@ kb_assert_entity_no_audit(Type, Props) :-
|
|
|
284
290
|
)
|
|
285
291
|
)).
|
|
286
292
|
|
|
287
|
-
%% kb_log_entity_upsert(+Type, +Properties)
|
|
293
|
+
%% kb_log_entity_upsert(+ChangeKind, +Type, +Properties)
|
|
288
294
|
% Append the audit entry for a successfully committed entity upsert.
|
|
289
|
-
kb_log_entity_upsert(Type, Props) :-
|
|
295
|
+
kb_log_entity_upsert(ChangeKind, Type, Props) :-
|
|
290
296
|
memberchk(id=Id, Props),
|
|
297
|
+
memberchk(ChangeKind, [created, updated]),
|
|
291
298
|
with_kb_mutex((
|
|
292
299
|
get_time(Timestamp),
|
|
293
300
|
format_time(atom(TS), '%FT%T%:z', Timestamp),
|
|
294
|
-
assert_changeset(TS, upsert, Id, Type-Props)
|
|
301
|
+
assert_changeset(TS, upsert, Id, Type-[change_kind=ChangeKind|Props])
|
|
295
302
|
)).
|
|
296
303
|
|
|
297
304
|
%% kb_retract_entity(+Id)
|
|
298
305
|
% Remove an entity from the KB with audit logging.
|
|
299
306
|
kb_retract_entity(Id) :-
|
|
307
|
+
( once(kb_entity(Id, Type, Props))
|
|
308
|
+
-> entity_delete_audit_props(Id, Props, AuditProps)
|
|
309
|
+
; Type = unknown,
|
|
310
|
+
AuditProps = [id=Id]
|
|
311
|
+
),
|
|
312
|
+
kb_retract_entity(Id, Type, AuditProps).
|
|
313
|
+
|
|
314
|
+
%% kb_retract_entity(+Id, +Type, +AuditProps)
|
|
315
|
+
% Remove an entity from the KB and log the provided delete payload.
|
|
316
|
+
kb_retract_entity(Id, Type, AuditProps) :-
|
|
300
317
|
kb_graph(Graph),
|
|
301
318
|
with_kb_mutex((
|
|
302
319
|
% Create entity URI
|
|
@@ -306,9 +323,30 @@ kb_retract_entity(Id) :-
|
|
|
306
323
|
% Log to audit
|
|
307
324
|
get_time(Timestamp),
|
|
308
325
|
format_time(atom(TS), '%FT%T%:z', Timestamp),
|
|
309
|
-
assert_changeset(TS, delete, Id,
|
|
326
|
+
assert_changeset(TS, delete, Id, Type-AuditProps)
|
|
310
327
|
)).
|
|
311
328
|
|
|
329
|
+
entity_delete_audit_props(Id, Props, AuditProps) :-
|
|
330
|
+
findall(Key=Value,
|
|
331
|
+
( member(Key, [title, source, text_ref]),
|
|
332
|
+
memberchk(Key=RawValue, Props),
|
|
333
|
+
audit_property_value(RawValue, Value)
|
|
334
|
+
),
|
|
335
|
+
OptionalProps),
|
|
336
|
+
AuditProps = [id=Id|OptionalProps].
|
|
337
|
+
|
|
338
|
+
audit_property_value(RawValue, Value) :-
|
|
339
|
+
( RawValue = ^^(Inner, _)
|
|
340
|
+
-> Value = Inner
|
|
341
|
+
; RawValue = literal(type(_, Inner))
|
|
342
|
+
-> Value = Inner
|
|
343
|
+
; RawValue = literal(lang(_, Inner))
|
|
344
|
+
-> Value = Inner
|
|
345
|
+
; RawValue = literal(Inner)
|
|
346
|
+
-> Value = Inner
|
|
347
|
+
; Value = RawValue
|
|
348
|
+
).
|
|
349
|
+
|
|
312
350
|
%% kb_entity(?Id, ?Type, ?Properties)
|
|
313
351
|
% Query entities from the KB.
|
|
314
352
|
% Properties is unified with a list of Key=Value pairs.
|
|
@@ -356,12 +394,18 @@ convert_legacy_prop(Prop, Prop, true).
|
|
|
356
394
|
kb_entities_by_source(SourcePath, Ids) :-
|
|
357
395
|
findall(Id,
|
|
358
396
|
(kb_entity(Id, _Type, Props),
|
|
359
|
-
|
|
360
|
-
source_value_atom(RawSource, SourceAtom),
|
|
397
|
+
entity_source_atom(Props, SourceAtom),
|
|
361
398
|
sub_atom(SourceAtom, _, _, _, SourcePath)),
|
|
362
399
|
RawIds),
|
|
363
400
|
sort(RawIds, Ids).
|
|
364
401
|
|
|
402
|
+
entity_source_atom(Props, SourceAtom) :-
|
|
403
|
+
( memberchk(sourceFile=RawSourceFile, Props)
|
|
404
|
+
-> source_value_atom(RawSourceFile, SourceAtom)
|
|
405
|
+
; memberchk(source=RawSource, Props),
|
|
406
|
+
source_value_atom(RawSource, SourceAtom)
|
|
407
|
+
).
|
|
408
|
+
|
|
365
409
|
source_value_atom(Value, Atom) :-
|
|
366
410
|
( atom(Value)
|
|
367
411
|
-> Atom = Value
|