File Coverage

blib/lib/Algorithm/SAT/Backtracking/Ordered/DPLL.pm
Criterion Covered Total %
statement 39 48 81.2
branch 8 14 57.1
condition 1 11 9.0
subroutine 8 9 88.8
pod 1 1 100.0
total 57 83 68.6


line stmt bran cond sub pod time code
1             package Algorithm::SAT::Backtracking::Ordered::DPLL;
2 2     2   1339 use Hash::Ordered;
  2         3  
  2         49  
3 2     2   7 use base "Algorithm::SAT::Backtracking::DPLL";
  2         17  
  2         442  
4             use Algorithm::SAT::Backtracking::DPLL
5 2     2   9 "Algorithm::SAT::Backtracking::Ordered";
  2         3  
  2         16  
6 2     2   9 use strict;
  2         2  
  2         42  
7 2     2   7 use warnings;
  2         2  
  2         627  
8             our $VERSION = "0.12";
9              
10             ##Ordered implementation, of course has its costs
11             sub solve {
12 18     18 1 35 my $self = shift;
13 18         14 my $variables = shift;
14 18         19 my $clauses = shift;
15 18 100       45 my $model = defined $_[0] ? shift : Hash::Ordered->new;
16 18         98 return $self->SUPER::solve( $variables, $clauses, $model );
17             }
18              
19             sub _up {
20 15     15   33 my $self = shift;
21 15         10 my $variables = shift;
22 15         15 my $clauses = shift;
23 15 50       21 my $model = defined $_[0] ? shift : Hash::Ordered->new;
24              
25             #Finding single clauses that must be true, and updating the model
26 57         92 ( @{$_} != 1 )
27             ? ()
28             : ( substr( $_->[0], 0, 1 ) eq "-" ) ? (
29 15         26 do {
30 7         10 my $literal = substr( $_->[0], 1 );
31 7         16 $model->set( $literal => 0 );
32 7         53 $self->_delete_from_index( $literal, $clauses );
33             }
34              
35             #remove the positive clause form OR's and add it to the model with a false value
36             )
37             : (
38             $self->_add_literal( "-" . $_->[0], $clauses )
39             and $model->set( $_->[0] => 1 )
40              
41             ) # if the literal is present, remove it from SINGLE ARRAYS in $clauses and add it to the model with a true value
42 15 50 0     13 for ( @{$clauses} );
    100          
43 15         27 return $model;
44             }
45              
46             sub _add_literal {
47 0     0   0 my $self = shift;
48 0         0 my $literal = shift;
49 0         0 my $clauses = shift;
50 0         0 my $model = shift;
51 0 0       0 $literal
52             = ( substr( $literal, 0, 1 ) eq "-" )
53             ? $literal
54             : substr( $literal, 1 );
55             return
56 0 0 0     0 if $model
      0        
57             and $model->exists($literal)
58             and $model->set( $literal, 1 ); #avoid cycle if already set
59             #remove the literal from the model (set to false)
60 0         0 $model->set( $literal, 1 );
61 0         0 $self->_delete_from_index( $literal, $clauses );
62 0         0 return 1;
63             }
64              
65             sub _choice {
66 14     14   12 my $self = shift;
67 14         14 my $variables = shift;
68 14         13 my $model = shift;
69 14         10 my $choice;
70 14         12 foreach my $variable ( @{$variables} ) {
  14         20  
71 33 100 50     105 $choice = $variable and last if ( !$model->exists($variable) );
72             }
73 14         86 return $choice;
74             }
75              
76             1;
77              
78             =encoding utf-8
79              
80             =head1 NAME
81              
82             Algorithm::SAT::Backtracking::Ordered::DPLL - A DPLL Backtracking SAT ordered implementation
83              
84             =head1 SYNOPSIS
85              
86              
87             # You can use it with Algorithm::SAT::Expression
88             use Algorithm::SAT::Expression;
89              
90             my $expr = Algorithm::SAT::Expression->new->with("Algorithm::SAT::Backtracking::Ordered::DPLL");
91             $expr->or( '-foo@2.1', 'bar@2.2' );
92             $expr->or( '-foo@2.3', 'bar@2.2' );
93             $expr->or( '-baz@2.3', 'bar@2.3' );
94             $expr->or( '-baz@1.2', 'bar@2.2' );
95             my $model = $exp->solve();
96              
97             # Or you can use it directly:
98             use Algorithm::SAT::Backtracking::Ordered::DPLL;
99             my $solver = Algorithm::SAT::Backtracking::Ordered::DPLL->new;
100             my $variables = [ 'blue', 'green', 'yellow', 'pink', 'purple' ];
101             my $clauses = [
102             [ 'blue', 'green', '-yellow' ],
103             [ '-blue', '-green', 'yellow' ],
104             [ 'pink', 'purple', 'green', 'blue', '-yellow' ]
105             ];
106              
107             my $model = $solver->solve( $variables, $clauses );
108              
109              
110             =head1 DESCRIPTION
111              
112              
113             Algorithm::SAT::Backtracking::Ordered::DPLL is a pure Perl implementation of a DPLL SAT Backtracking solver, in this variant of L we keep the order of the model updates and return a L as result.
114              
115             Look at L for a theory description.
116              
117             Look also at the test file for an example of usage.
118              
119             L use this module to solve Boolean expressions.
120              
121             =head1 METHODS
122              
123             Inherits all the methods from L and override/implements the following:
124              
125             =head2 SOLVE
126              
127             $expr->solve();
128              
129             in this case returns a L.
130              
131             =head1 LICENSE
132              
133             Copyright (C) mudler.
134              
135             This library is free software; you can redistribute it and/or modify
136             it under the same terms as Perl itself.
137              
138             =head1 AUTHOR
139              
140             mudler Emudler@dark-lab.netE
141              
142             =head1 SEE ALSO
143              
144             L, L, L, L
145              
146             =cut
147