1/*  Read-only lookup of the summary table of the Calculiva plank waste study v1.0.0
    2    (doi:10.7910/DVN/8VL3MW). Computes nothing; the layout engine is not included.
    3    Code: MIT. Data: CC BY 4.0, see calculiva_waste_benchmark_data.pl for the attribution.
    4*/
    5:- module(calculiva_waste_benchmark,
    6          [ waste_dataset_version/1,   % -Version
    7            waste_allowances/1,        % -ListOfPercent
    8            waste_rows/1,              % -Rows
    9            waste_lookup/5,            % +FormatId, +Offset, +Reuse, +KerfMm, -Row
   10            waste_shortfall_pct/3      % +Row, +Allowance, -Pct
   11          ]).   12:- use_module(library(error)).   13:- use_module(library(lists)).   14:- use_module(calculiva_waste_benchmark_data).
 waste_dataset_version(-Version:atom) is det
   17waste_dataset_version(V) :- dataset_version(V).
 waste_allowances(-Allowances:list(integer)) is det
   20waste_allowances([5, 8, 10, 15]).
 waste_rows(-Rows:list) is det
All 42 rows, in the order of summary.csv, as waste_row(FormatId, FormatOrigin, Offset, Reuse, KerfMm, ReferenceOnly, Cases, waste(Min,Median,Mean,Max), [allowance(Pct,Short,Exact,Excess,ShortPct,ExcessPct), ...]).
   26waste_rows(Rows) :-
   27    findall(waste_row(F, Or, O, R, K, Ref, C, W, A),
   28            summary_row(F, Or, O, R, K, Ref, C, W, A), Rows).
 waste_lookup(+FormatId:atom, +Offset:atom, +Reuse:boolean, +KerfMm:integer, -Row) is semidet
Offset is '0', '1/2' or '1/3'; Reuse is true or false. Fails when the combination is absent.
   32waste_lookup(F, O, R, K, waste_row(F, Or, O, R, K, Ref, C, W, A)) :-
   33    summary_row(F, Or, O, R, K, Ref, C, W, A), !.
 waste_shortfall_pct(+Row, +Allowance:integer, -Pct:float) is det
Share of rooms (percent) where a flat 5, 8, 10 or 15 % allowance orders less than the engine count. Raises a domain error for any other allowance.
   38waste_shortfall_pct(waste_row(_, _, _, _, _, _, _, _, A), Allowance, Pct) :-
   39    must_be(integer, Allowance),
   40    (   memberchk(Allowance, [5, 8, 10, 15])
   41    ->  true
   42    ;   domain_error(oneof([5, 8, 10, 15]), Allowance)
   43    ),
   44    memberchk(allowance(Allowance, _, _, _, Pct, _), A)