]> Dogcows Code - chaz/p5-Acme-Test-LogicalEquivalence/blob - lib/Acme/Test/LogicalEquivalence.pm
Version 0.001
[chaz/p5-Acme-Test-LogicalEquivalence] / lib / Acme / Test / LogicalEquivalence.pm
1 package Acme::Test::LogicalEquivalence;
2 # ABSTRACT: Test if expressions are logically equivalent
3 # KEYWORDS: test logic
4
5 use 5.008;
6 use warnings;
7 use strict;
8
9 our $VERSION = '0.001'; # VERSION
10
11 use Exporter qw(import);
12 use Test::More;
13 use namespace::clean -except => [qw(import)];
14
15 our @EXPORT_OK = qw(is_logically_equivalent);
16
17
18 sub is_logically_equivalent {
19 my $numvars = shift;
20 my $sub1 = shift;
21 my $sub2 = shift;
22
23 my $equivalence = 1;
24
25 for (my $i = 0; $i < 2 ** $numvars; ++$i) {
26 my @vars = split(//, substr(unpack("B32", pack('N', $i)), -$numvars));
27
28 (local $a, local $b) = @vars;
29 my $r1 = !!$sub1->(@vars);
30
31 (local $a, local $b) = @vars;
32 my $r2 = !!$sub2->(@vars);
33
34 my $test = !($r1 xor $r2);
35
36 my $args = join(', ', map { $_ ? 'T' : 'F' } @vars);
37 ok($test, "expr1($args) <=> expr2($args)");
38
39 $equivalence = '' if !$test;
40 }
41
42 return $equivalence;
43 }
44
45 1;
46
47 __END__
48
49 =pod
50
51 =encoding UTF-8
52
53 =head1 NAME
54
55 Acme::Test::LogicalEquivalence - Test if expressions are logically equivalent
56
57 =head1 VERSION
58
59 version 0.001
60
61 =head1 SYNOPSIS
62
63 use Test::More;
64 use Acme::Test::LogicalEquivalence qw(is_logically_equivalent);
65
66 # test two expressions with 2 variables using the special vars $a and $b
67 is_logically_equivalent(2, sub { $a && $b }, sub { $b && $a });
68
69 # same as above
70 is_logically_equivalent(2, sub { $_[0] && $_[1] }, sub { $_[1] && $_[0] });
71
72 # you can do as many vars as you like
73 is_logically_equivalent(3, sub { $_[0] || ($_[1] && $_[2]) },
74 sub { ($_[0] || $_[1]) && ($_[0] || $_[2]) });
75
76 done_testing;
77
78 =head1 DESCRIPTION
79
80 Some expressions are "logically equivalent" to other expressions, but it may not be easy to tell if
81 one or both of the expressions are reasonably complicated. Or maybe you're like many other people
82 and are too lazy to go through the effort... Either way, why not let your computer prove logical
83 equivalence for you?
84
85 =head1 FUNCTIONS
86
87 =head2 is_logically_equivalent
88
89 Test logical equivalence of two subroutines.
90
91 my $is_equivalent = is_logically_equivalent($numvars, &sub1, &sub2);
92
93 This will execute both of the subroutines one or more times (depending on how many variables you
94 specify) with different inputs. The subroutines shall be considered logically equivalent if, for all
95 combinations of inputs, they both return the same thing.
96
97 Returns true if the subroutines are logically equivalent, false otherwise.
98
99 =head1 SEE ALSO
100
101 =over 4
102
103 =item *
104
105 What is logical equivalence? Start here: L<https://en.wikipedia.org/wiki/Logical_equivalence>
106
107 =back
108
109 =head1 AUTHOR
110
111 Charles McGarvey <chazmcgarvey@brokenzipper.com>
112
113 =head1 COPYRIGHT AND LICENSE
114
115 This software is copyright (c) 2016 by Charles McGarvey.
116
117 This is free software; you can redistribute it and/or modify it under
118 the same terms as the Perl 5 programming language system itself.
119
120 =cut
This page took 0.043801 seconds and 4 git commands to generate.