1 /*
2  * Copyright (c) 2018 Helmut Neemann
3  * Use of this source code is governed by the GPL v3 license
4  * that can be found in the LICENSE file.
5  */
6 package de.neemann.digital.analyse;
7 
8 import de.neemann.digital.analyse.expression.Variable;
9 import de.neemann.digital.analyse.quinemc.BoolTable;
10 import de.neemann.digital.analyse.quinemc.BoolTableByteArray;
11 import de.neemann.digital.analyse.quinemc.TableReducer;
12 import de.neemann.digital.analyse.quinemc.ThreeStateValue;
13 import de.neemann.digital.core.Signal;
14 import junit.framework.TestCase;
15 
16 import java.util.ArrayList;
17 import java.util.List;
18 
19 public class BoolTableExpandedTest extends TestCase {
20 
testRegression()21     public void testRegression() {
22         checkTable(new Signals("a", "b").list());
23         checkTable(new Signals("a", "c").list());
24         checkTable(new Signals("a", "d").list());
25         checkTable(new Signals("b", "c").list());
26         checkTable(new Signals("b", "d").list());
27         checkTable(new Signals("c", "d").list());
28     }
29 
checkTable(ArrayList<Signal> in1)30     private void checkTable(ArrayList<Signal> in1) {
31         ArrayList<Signal> in2 = new Signals("a", "b", "c", "d").list();
32         List<Variable> vars = new Vars("a", "b", "c", "d").list();
33 
34         check(new BoolTableByteArray(new byte[]{1, 1, 0, 1}), in1, in2, vars);
35         check(new BoolTableByteArray(new byte[]{0, 1, 1, 0}), in1, in2, vars);
36         check(new BoolTableByteArray(new byte[]{1, 0, 0, 1}), in1, in2, vars);
37         check(new BoolTableByteArray(new byte[]{0, 0, 0, 1}), in1, in2, vars);
38         check(new BoolTableByteArray(new byte[]{0, 1, 1, 1}), in1, in2, vars);
39     }
40 
check(BoolTableByteArray e, ArrayList<Signal> in1, ArrayList<Signal> in2, List<Variable> vars)41     private void check(BoolTableByteArray e, ArrayList<Signal> in1, ArrayList<Signal> in2, List<Variable> vars) {
42         BoolTableExpanded bt = new BoolTableExpanded(e, in1, in2);
43 
44         TableReducer tr = new TableReducer(vars, bt);
45 
46         assertTrue(tr.canReduceOnlyCheckTable());
47 
48         List<Variable> v = tr.getVars();
49         assertEquals(in1.size(), v.size());
50         for (int i = 0; i < v.size(); i++)
51             assertEquals(in1.get(i).getName(), v.get(i).getIdentifier());
52 
53         BoolTable t1 = tr.getTable();
54         assertEquals(e.size(), t1.size());
55         for (int r = 0; r < e.size(); r++)
56             assertEquals(e.get(r), t1.get(r));
57     }
58 
testCombined()59     public void testCombined() {
60         ArrayList<Signal> in1 = new Signals("b", "c").list();
61         ArrayList<Signal> in2 = new Signals("a", "b", "c", "d").list();
62         List<Variable> vars = new Vars("a", "b", "c", "d").list();
63 
64         BoolTableExpanded bt = new BoolTableExpanded(new BoolTableByteArray(new byte[]{1, 1, 0, 0}), in1, in2);
65         TableReducer tr = new TableReducer(vars, bt);
66         assertTrue(tr.canReduce());
67         List<Variable> v = tr.getVars();
68         assertEquals(1, v.size());
69         assertEquals("b", v.get(0).getIdentifier());
70         BoolTable t1 = tr.getTable();
71         assertEquals(ThreeStateValue.one, t1.get(0));
72         assertEquals(ThreeStateValue.zero, t1.get(1));
73     }
74 
75     private static class ListBuilder<A, B> {
76         private final ArrayList<A> list;
77         private Factory<A, B> factory;
78 
ListBuilder(Factory<A, B> factory)79         ListBuilder(Factory<A, B> factory) {
80             this.factory = factory;
81             list = new ArrayList<>();
82         }
83 
ListBuilder(Factory<A, B> factory, B[] bs)84         ListBuilder(Factory<A, B> factory, B[] bs) {
85             this(factory);
86             for (B b : bs)
87                 add(b);
88         }
89 
add(B b)90         public ListBuilder<A, B> add(B b) {
91             list.add(factory.make(b));
92             return this;
93         }
94 
list()95         public ArrayList<A> list() {
96             return list;
97         }
98     }
99 
100     public class Signals extends ListBuilder<Signal, String> {
Signals(String... s)101         Signals(String... s) {
102             super((a) -> new Signal(a, null), s);
103         }
104     }
105 
106     public class Vars extends ListBuilder<Variable, String> {
Vars(String... s)107         Vars(String... s) {
108             super(Variable::new, s);
109         }
110     }
111 
112     private interface Factory<A, B> {
make(B b)113         A make(B b);
114     }
115 }
116