kibi-core 0.29.0 → 0.30.0

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/model_check.pl +37 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-core",
3
- "version": "0.29.0",
3
+ "version": "0.30.0",
4
4
  "private": false,
5
5
  "description": "Core Prolog modules and RDF graph logic for Kibi",
6
6
  "type": "module",
@@ -334,7 +334,7 @@ relation_problem("excludes", Actual, Expected, What, Reason) :-
334
334
  % member ending in .m for *.m. *.m is allowed only when *.m is.
335
335
  % eq Compares the spellings exactly, as for every other reader.
336
336
 
337
- source_matching(Certificate, references(Files)) :-
337
+ source_matching(Certificate, references(Files, Case)) :-
338
338
  get_dict(source, Certificate, Source),
339
339
  is_dict(Source),
340
340
  get_dict(reader, Source, Reader),
@@ -343,12 +343,23 @@ source_matching(Certificate, references(Files)) :-
343
343
  ( get_dict(files, Source, RawFiles)
344
344
  -> ( is_list(RawFiles) -> maplist(text_string, RawFiles, Files) ; text_string(RawFiles, File), Files = [File] )
345
345
  ; Files = []
346
+ ),
347
+ % Some languages ignore letter case in the names they call, throw and
348
+ % import (PHP classes, methods and functions): excludes then also fails
349
+ % on a member that differs from an item only in case.
350
+ ( get_dict(extract, Source, RawExtract),
351
+ text_string(RawExtract, Extract),
352
+ memberchk(Extract, ["calls", "thrown", "imports"])
353
+ -> Case = fold
354
+ % mutalog-disable-next-line goal_true: Case is only compared with ==, so an unbound Case reads as exact
355
+ ; Case = exact
346
356
  ).
347
357
  source_matching(_, literal).
348
358
 
349
359
  member_separator(".").
350
360
  member_separator("/").
351
361
  member_separator("::").
362
+ member_separator("\\").
352
363
 
353
364
  % extends_member(+Member, +Stem): Member is Stem or lies under it at a
354
365
  % segment boundary. The empty stem (from the item "*") covers everything.
@@ -418,6 +429,16 @@ exclude_match(Actual, Expected, How) :-
418
429
  -> How = possible
419
430
  ).
420
431
 
432
+ % folded_match(+Actual, +Expected, -How): Actual may be what Expected names
433
+ % once letter case is ignored. Called only for a pair exclude_match/3
434
+ % rejected, so a match here is one that only letter case makes.
435
+ folded_match(Actual, Expected, possible) :-
436
+ string_lower(Actual, LowerActual),
437
+ string_lower(Expected, LowerExpected),
438
+ exclude_match(LowerActual, LowerExpected, _),
439
+ % mutalog-disable-next-line cut: the caller sorts the pairs it collects, so a second answer adds nothing
440
+ !.
441
+
421
442
  % certain_match(+Actual, +Expected): Actual certainly is what Expected names
422
443
  % (includes, subset_of).
423
444
  certain_match(Actual, Expected) :- Actual == Expected, !.
@@ -447,7 +468,9 @@ files_text(Files, Text) :-
447
468
  ).
448
469
 
449
470
  excluded_text(Files, Actual-Expected-How, Text) :-
450
- ( How == certain, Actual == Expected
471
+ ( \+ exclude_match(Actual, Expected, _)
472
+ -> format(string(Text), "~w (it may be ~w: the names differ only in letter case, which some languages ignore)", [Actual, Expected])
473
+ ; Actual == Expected
451
474
  -> Text = Actual
452
475
  ; How == certain
453
476
  -> format(string(Text), "~w (within ~w)", [Actual, Expected])
@@ -461,11 +484,18 @@ excluded_text(Files, Actual-Expected-How, Text) :-
461
484
  ; format(string(Text), "~w (a shorter name that may be ~w)", [Actual, Expected])
462
485
  ).
463
486
 
464
- % reference_relation_problem(+Operator, +Actual, +Expected, +Files, +What,
487
+ % reference_relation_problem(+Operator, +Actual, +Expected, +Matching, +What,
465
488
  % -Reason) fails when the relation holds under the reference matching above.
466
- reference_relation_problem("excludes", Actual, Expected, Files, What, Reason) :-
489
+ reference_relation_problem("excludes", Actual, Expected, references(Files, Case), What, Reason) :-
467
490
  !,
468
- findall(A-E-How, (member(A, Actual), member(E, Expected), exclude_match(A, E, How)), Pairs0),
491
+ findall(A-E-How,
492
+ ( member(A, Actual), member(E, Expected),
493
+ ( exclude_match(A, E, How)
494
+ -> true
495
+ ; Case == fold, folded_match(A, E, How)
496
+ )
497
+ ),
498
+ Pairs0),
469
499
  sort(Pairs0, Pairs),
470
500
  Pairs \== [],
471
501
  include(certain_pair, Pairs, Certain),
@@ -600,8 +630,8 @@ obligation_result("set_relation", Obligation, model(_, _, source(Actual, _, _, _
600
630
  dict_text(Obligation, operator, Operator),
601
631
  obligation_strings(Obligation, Expected),
602
632
  What = "the members Kibi read from the source",
603
- ( ( Matching = references(Files)
604
- -> reference_relation_problem(Operator, Actual, Expected, Files, What, Reason)
633
+ ( ( Matching = references(_, _)
634
+ -> reference_relation_problem(Operator, Actual, Expected, Matching, What, Reason)
605
635
  ; relation_problem(Operator, Actual, Expected, What, Reason)
606
636
  )
607
637
  -> Result = problem(Reason)