Incorrect warning during "make" operation

I’m using: SWI-Prolog version 8.1.9.

PREFACE: If the code looks ‘odd’ below, be aware I have to avoid formal dynamic goal calling predicates like ‘call/1’, etc. because the PEngines sandbox rejects such attempts resulting in a sandbox fatal error. That is why I’m taking the following unusual steps to “stitch” together a dynamic call. Also, the reason I want to pass the filter predicate inside a variable is because I have multiple filter predicates with the same arity. I’m only showing one of the filter predicate calls for the purposes of brevity.

The code below generates the following warning during a make operation:

Warning: The predicates below are not defined. If these are defined
Warning: at runtime using assert/1, use :- dynamic Name/Arity.
Warning: 
Warning: fsg_is_score_too_low/0, which is referenced by
Warning: 1-st clause of filter_score_group/2

However, the code below works properly and at runtime, instead of fsg_is_score_too_low being called with zero arguments, it is called with 2 arguments as desired. I know this because when I trace out the code in the graphical debugger it shows a call to fsg_is_score_too_low/2 and not fsg_is_score_too_low/0. The latter would fail anyways because no such 0-arity version of fsg_is_score_too_low exists. Therefore, the compiler is throwing an incorrect warning. Fortunately, it is generating the correct code.

Here is the relevant code:

% Filter a score record by overall score.
% fsg_is_score_too_low(+ScoreGroup, +ScoreRecord)
fsg_is_score_too_low(_, ScoreRecord) :-
	extract_overall_score_from_score_record_val(ScoreRecord, OverallScore),
	OverallScore < 1,
	!.

% Support predicate for findall() operation.  Select the next score 
%	record that should not be filtered.
% filter_score_group_1(+FilterFunc, +ScoreGroup, -ScoreRecord_filtered)
filter_score_group_1(FilterFunc, ScoreGroup, ScoreRecord_filtered) :-
	member(ScoreRecord_filtered, ScoreGroup),
	CallFilter =.. [ FilterFunc, ScoreGroup, ScoreRecord_filtered ],
	\+ CallFilter.

% ======= CALLING CODE ========

% filter_score_group(+ScoreGroup, -ScoreGroup_filtered)
filter_score_group(ScoreGroup, ScoreGroup_filtered) :-	
	% First filter by overall score to reduce processing time.
	FilterFunc_1 = fsg_is_score_too_low,
	findall(
		ScoreRecord_filtered_1, 
		filter_score_group_1(
			% Filter predicate.
			FilterFunc_1,
			% Input score group.
			ScoreGroup, 
			ScoreRecord_filtered_1), 
		% Filtered score group.
		ScoreGroup_filtered_1),	
		!.

Never say never, but I’ve never seen these errors being wrong. The program is incomplete though and the problem doesn’t reproduce.

That shouldn’t work unless there is an error in the sandbox. Please share the complete code somewhere so it can be reproduced.

In daily use, there would be once in a while a warning that is misleading at first glance. Those cases are always caused by me typing a full-stop, “.” when I meant a comma, “,” or forgetting an argument or something of this sort.

To me this says “the warnings are great and they catch the kind of errors that linters are supposed to catch”. The whole linter-compiler separation seems to be a side effect of having made questionable choices early in the design and implementation of a language (looking at you, Python :wink: )

In terms of “ergonomy” SWI-Prolog is worth of a case study to be put in textbooks, as a good example. It could be improved but that’s a truism.