Library(prolog_coverage) - working with predicates generated via persistent/1

$ swipl --version
SWI-Prolog version 10.0.0 for x64-win64

Using library(prolog_coverage) on a module that uses library(persistency).

For code coverage for persistent/1 was able to increase the code coverage by adding tests for the dynamicly created four predicates resulting in this

   90 ### ⮰
      ++20 ⮰
      ++4,727 ⮰
      ++21,486 ⮰
      +55,950-20             :- persistent(pred_def(name:atom, arity:integer, module:atom, file:atom, line:integer)).

There is now just the one remaining ### that I have no idea of what it could be.

Any ideas? Is it a predicate, an artifact of code coverage that can be removed, other?

Any ideas on how to get a line in the cov report to show what it could be?


Gave Claude the links to the SWI-Prolog library code on GitHub and noted the relevant files in the project and Claude thinks

   90 ### ⮰                          ← The directive itself: never "executed"
      ++20 ⮰                          ← Generated predicate variant 1
      ++4,727 ⮰                       ← Generated predicate variant 2
      ++21,486 ⮰                      ← Generated predicate variant 3
      +55,950-20                      ← Generated predicate variant 4
             :- persistent(pred_def(name:atom, arity:integer, module:atom, file:atom, line:i

If that is true would like to find a way to remove such lines from the cov report so that the report shows 100% coverage for the module. Currently Claude will search for ### lines and thus it is like having a wrench thrown into the clock works.

I don’t think that is true. The directive is term-expanded to a set of predicates. I suspect one of them is not used by your tests. Which one is a bit hard to tell. Ideally the system should provide better feedback for this, but I’m not sure how.

I’d create a module with only this declaration and list the content so you can understand what is going on.

Result confirms that is true.



There are five, not four generated predicates from persistent/1.

From documentation

The persistent/1 expands each declaration into four predicates:

  • name(Arg, ...)
  • assert_name(Arg, ...)
  • retract_name(Arg, ...)
  • retractall_name(Arg, ...)

using

:- persistent(pred_def(name:atom, arity:integer, module:atom, file:atom, line:integer)).

the following are generated

Generated predicate type
pred_def/5 base
assert_pred_def/5 assert_
asserta_pred_def/5 asserta_
retract_pred_def/5 retract_
retractall_pred_def/5 retractall_

   90 ++21,486 ⮰
      ++20 ⮰
      ++4,987 ⮰
      +55,950-20 ⮰
      ++20                   :- persistent(pred_def(name:atom, arity:integer, module:atom, file:atom, line:integer)).

Jan updated the SWI-Prolog documentation for library(persistency)

Filename: test_persistency.pl

% Minimal Fixture: Single persistent/1 directive with arity 1
% Purpose: Isolate coverage behavior for one persistent declaration
%
% This module tests the simplest case:
% - One persistent/1 directive
% - Arity 1 (single argument)
% - Generates 5 predicates: foo/1, assert_foo/1, asserta_foo/1, retract_foo/1, retractall_foo/1

:- module(test_persistency, []).

:- use_module(library(persistency)).

% Single persistent declaration - should generate exactly 5 predicates
:- persistent(foo(value:any)).
$ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 10.0.0)

4 ?- [test_persitency].
true.

5 ?- findall(Name/Arity,         (current_predicate(test_persistency:Name/Arity),         sub_atom(Name, _, _, _, foo)),         Preds),sort(Preds, 
SortedPreds),forall(member(Name/Arity, SortedPreds), format('~w/~w~n', [Name, Arity])).
assert_foo/1
asserta_foo/1
foo/1
retract_foo/1
retractall_foo/1
Preds = [retract_foo/1, retractall_foo/1, foo/1, asserta_foo/1, assert_foo/1],
SortedPreds = [assert_foo/1, asserta_foo/1, foo/1, retract_foo/1, retractall_foo/1].

Added to the docs.