Skip to content

Commit 7efa72b

Browse files
committed
rewriting
1 parent c4da3e6 commit 7efa72b

1 file changed

Lines changed: 35 additions & 100 deletions

File tree

‎lib/ProblemSolver.pm6‎

Lines changed: 35 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,53 @@
1-
use ProblemSolver::State;
21
unit class ProblemSolver;
32

4-
has Bool $.stop-on-first-solution = False;
5-
has Bool $!found-solution = False;
6-
has Array of Callable %!constraints{Signature};
7-
has $!variables handles <add-variable> = ProblemSolver::State.new;
8-
#has ProblemSolver::State $!variables handles <add-variable> .= new;
9-
has &.print-found is rw;
10-
has Array of Callable %!heuristics;
3+
has %.variables;
4+
has Bag $.vars .= new;
5+
has %.constraints{Set};
6+
has %.heuristics{Str};
7+
has %.found;
118

12-
method add-constraint(&const) {
13-
%!constraints{&const.signature}.push: &const
9+
multi method create-variable(Str $name where { not %!variables{$_}:exists }, Bag() \values) {
10+
$!vars = |$!vars (+) Pair.new: $name, 1;
11+
%!variables = |%!variables, $name => values;
1412
}
1513

16-
method add-heuristic($var, &heu) {
17-
%!heuristics{$var}.push: &heu
14+
multi method create-variable(Bag $names where { %!variables{$_.none}:exists }, Bag() \values) {
15+
$!vars = $!vars (+) $names;
16+
%!variables = |%!variables, |do for $names.keys -> $name { $name => values }
1817
}
1918

20-
method solve {
21-
for $!variables.found-vars -> $key {
22-
self!remove-values($!variables, :variable($key), :value($!variables.get($key))) if %!heuristics{$key}:exists;
23-
}
24-
self!solve-all($!variables)
25-
}
26-
27-
method !solve-all($todo) {
28-
do if $todo.found-everything {
29-
my %tmp = $todo.found-hash;
30-
do if self!run-constraints(%tmp, :debug) {
31-
$!found-solution = True;
32-
%tmp
33-
}
34-
} else {
35-
my @resp;
36-
my $key = $todo.next-var;
37-
for $todo.iterate-over($key) -> $new {
38-
next unless self!run-constraints($new.found-hash) or $new.has-empty-vars;
39-
self!remove-values($new, :variable($key), :value($new.get($key))) if %!heuristics{$key}:exists;
40-
&!print-found($new.found-hash) if &!print-found;
41-
@resp.push: self!solve-all($new);
42-
last if $!stop-on-first-solution and $!found-solution
43-
}
44-
|@resp
45-
}
19+
method add-constraint(Set() \vars where {%!variables{vars.keys.all}:exists}, &constraint) {
20+
%!constraints{vars}.push: &constraint
4621
}
4722

48-
method !remove-values($todo, Str :$variable, :$value) {
49-
if %!heuristics{$variable}:exists {
50-
for @( %!heuristics{$variable} ) -> &func {
51-
func($todo, $value)
52-
}
53-
}
23+
method add-heuristic(Set() \vars where {%!variables{vars.keys.all}:exists}, &heuristic) {
24+
%!heuristics{$_}.push: &heuristic for vars.keys
5425
}
5526

56-
method !run-constraints(%values, :$debug) {
57-
my @cons = self!get-constraints-for-vars(%values);
58-
for @cons -> &func {
59-
return False if not func(|%values)
60-
}
61-
True
27+
multi method remove-possibility(Str \name where {%!variables{name}:exists}, \value) {
28+
%!variables{name} = %!variables{name} (-) bag(value xx %!variables{name}{value});
29+
fail if %!variables{name}.elems == 0;
30+
%!variables{name} = %!variables{name}.keys[0] if %!variables{name}.elems == 1;
6231
}
6332

64-
method !get-constraints-for-vars(%vars) {
65-
my @keys = %!constraints.keys.grep: -> \sig { %vars ~~ sig }
66-
|%!constraints{@keys}.map: |*
33+
method variable-bag {
34+
%!variables.keys.map(-> Str \var {
35+
slip var xx (($!vars{var} * %!constraints.pairs.grep(var ∈ *.key).map(*.value.elems).sum) || 1)
36+
}).Bag
6737
}
6838

69-
method constraint-vars(&red, @vars) {
70-
my $pars = &red.signature.params.elems;
71-
my @comb = @vars.combinations($pars);
72-
for @comb -> @pars {
73-
my $sig = @pars.map({":\${$_}!"}).join(", ");
74-
my $cal = @pars.map({"\${$_}"}).join(", ");
75-
use MONKEY-SEE-NO-EVAL;
76-
my &func = EVAL "-> $sig, | \{ red($cal)\}";
77-
no MONKEY-SEE-NO-EVAL;
78-
$.add-constraint(&func)
79-
}
80-
for @vars -> $var {
81-
my @v = @vars.grep(* !eq $var);
82-
$.add-heuristic($var, -> $todo, $value {
83-
for @v (&) $todo.not-found-vars -> $var {
84-
$todo.find-and-remove-from: $var.key, -> $v { not red($v, $value) }
85-
}
86-
})
87-
}
39+
method variable-order {
40+
|$.variable-bag.pairs.sort({-.value}).map: {.key}
8841
}
8942

90-
method unique-vars(@vars) {
91-
my @comb = @vars.combinations(2);
92-
for @comb -> @pars {
93-
my $sig = @pars.map({":\${$_}!"}).join(", ");
94-
my $cal = @pars.map({"\${$_}"}).join(", ");
95-
use MONKEY-SEE-NO-EVAL;
96-
my &func = EVAL "-> $sig, | \{ [!~~] $cal \}";
97-
no MONKEY-SEE-NO-EVAL;
98-
$.add-constraint(&func)
99-
}
100-
for @vars -> $var {
101-
my @v = @vars.grep(* !eq $var);
102-
$.add-heuristic($var, -> $todo, $value {
103-
for @v (&) $todo.not-found-vars -> $var {
104-
$todo.remove-from: $var.key, $value
105-
}
106-
})
107-
}
108-
}
109-
110-
method no-order-vars(+@vars) {
111-
for @vars -> $var {
112-
my @v = @vars.grep(* !eq $var);
113-
$.add-heuristic($var, -> $todo, $value {
114-
$todo.recursive-remove-from-vars: @v, $value
115-
})
116-
}
43+
method solve {
44+
# TODO: Run constraints
45+
# TODO: Run heuristics
46+
for $.variable-order -> $var {
47+
for |%!variables{$var}.pairs.sort(-*.value).map: *.key -> $value {
48+
my %variables = |%!variables, $var => $value;
49+
my $clone = self.clone: :variables(%variables), :vars($!vars (-) bag($var xx $!vars{$var}));
50+
note $clone
51+
}
52+
}
11753
}
118-

0 commit comments

Comments
 (0)