#!/usr/bin/env perl

use 5.022;
use strict;
use warnings;
use lib 'lib';
use Math::DifferenceSet::Planar;
use constant PDS => Math::DifferenceSet::Planar::;

$| = 1;

my $NUM = qr/(?:0|[1-9][0-9]*)/;

my $depth  = undef;
my $factor = undef;
while (@ARGV && $ARGV[0] =~ /^-(.+)/s) {
    my $opt = $1;
    shift @ARGV;
    last                            if $opt eq q[-];
    $depth  = $1,              next if $opt =~ /^d($NUM)\z/o;
    $depth  = $1, shift @ARGV, next
        if $opt eq 'd' && @ARGV && $ARGV[0] =~ /^($NUM)\z/o;
    $factor = $1,              next if $opt =~ /^f($NUM)\z/o;
    $factor = $1, shift @ARGV, next
        if $opt eq 'f' && @ARGV && $ARGV[0] =~ /^($NUM)\z/o;
    die "usage: pds_check [-d depth] [-f factor] [file]...\n";
}

my $syntax  = 0;
my $range   = 0;
my $not     = 0;
my $mult    = 0;
my $perhaps = 0;
my $proven  = 0;
while (<<>>) {
    s/^\s+//;
    my @e = split /\s+/;
    next if !@e;

    ++$syntax, next if grep { !/^$NUM\z/ } @e;
    my $check = PDS->check_elements(\@e, $depth, $factor);
    ++$range,  next if !defined $check;
    ++$mult,   next if $check eq '0';
    ++$not,    next if !$check;
    if ($check > 1) {
        ++$proven;
    }
    else {
        ++$perhaps;
    }
    print "@e\n";
}

warn "$syntax set(s) syntactically wrong\n"           if $syntax;
warn "$range set(s) not normalized\n"                 if $range;
warn "$not set(s) proven to be wrong\n"               if $not;
warn "$mult set(s) not passing multiplier check\n"    if $mult;
warn "$perhaps set(s) probably correct\n"             if $perhaps;
warn "$proven set(s) proven to be correct\n"          if $proven;

exit($syntax + $range + $not + $mult? 1: 0);

__END__
=head1 NAME

pds_check - perform planar difference set checks on lists of integers

=head1 SYNOPSIS

  pds_check [-d depth] [-f factor] [file]...

=head1 DESCRIPTION

This example program reads lists of numbers, one list per line, as
integer numbers separated by whitespace, checks them for being planar
difference sets, and writes those of them them back to standard output
that probably are.  An optional depth parameter governs the effort to
be taken for each check.  An optional factor greater than one forces a
check whether this factor is a multiplier.  A factor of one suppresses
the multiplier check.  Otherwise the multiplier check is performed with
a suitable factor.  The program concludes with a summary of the check
results on standard error.  The exit code is 0 (success) if no lines
had to be filtered out, otherwise 1.

=head1 DEPRECATION NOTICE

The I<check_elements> method of the Math::DifferenceSet::Planar library
this script is demonstrating is deprecated and will not be in the 1.0
release.  This example program will be dropped, too.

=head1 AUTHOR

Martin Becker, E<lt>becker-cpan-mp I<at> cozap.comE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright (c) 2021-2022 by Martin Becker, Blaubeuren.

This library is free software; you can distribute it and/or modify it
under the terms of the Artistic License 2.0 (see the LICENSE file).

=head1 DISCLAIMER OF WARRANTY

This library is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose.

=cut
