There are two problems with my pseudo-code. First off, add the red line. Second move the test code into the if() block.
Code:
assume values is initialized to all 0s, as is last_changed. length is the number of entries in value
void recursive (int values[], int length, int last_changed)
{
if (last_changed == length)
{
/* you've now generated all input values, so use them to test the equations */
test with current values[] array
return;
}
recursive(values, length, last_changed+1); /* A */
flip values[last_changed]
recursive(values, length, last_changed+1); /* B */
flip values[last_change] back to original value
}
length is the length of the values[] array - it's the count of how many inputs there are, not a count of the number of permutations
last_changed is the index in values[] you last flipped - this is also an index into the values array and not a count of the number of permutations tested - it indicates which level of recursion you're at, which is also the same as the bit you're currently changing to generate all permutations deeper in the search tree.
Each level of the recursive call sets a given index in value to 0, tests all the permutations of the higher indexes, then changes that given value to 1 and again tests all of the permutations at higher indexes
So the first call to recursive will set values[0] == 0 at comment A - this will then test all cases where values[0] == 0 and values[1..length-1] == both 0 and 1. The second recursive call at B will test all cases where value[0] == 1 and values[1..length-1] == both 0 and 1.
Think about it at the last level of recursion - last_changed will be the last index in values. All the others will have been set to something by previous calls. So the first call at A will make sure the last bit is 0 and call recursive. This final call will enter the if-block, test the equation, and then return. You'll then flip the last bit, call the code at B, and do the same test with that LSB at 1.
You'll return from that level, and move on to flip length-2 (the second to last bit). The call at B will then call recursion and go through the same steps, only with the second to last bit being the opposite value this time.
And then the code will return up one more level, flip the third most significant bit, and repeat the whole process again. And so on, until all bits have been tested.
You can ignore my edit - using the code as-is will generate the values in-order.
As for pruning the search tree, it's going to be a bit more difficult than I thought. You might want to experiment with using a 3rd value in values to indicate a don't care / uninitialized state. When you see this value in your code, test the equation with that value at both 0 and 1 (*) (you'll need to add this as an extra test at the start of the recursive function(), otherwise you'll only be checking when all values have been assigned a value so there's no children to prune from the search tress). If you get the same result for either input value, the uninitialized value doesn't matter in the final result. This means that you don't have to do the flip-and-check code for that bit, since you know that it doesn't change the result. You'll still have to track it, though, and you'll have to modify your print function to print both 0 and 1 as valid for these uninitialized values, though. In the end I think this is more than is expected for an assignment where you're just learning how to use recursion, but it might be fun to play with
* Or you could be smarter with your logic and instead of using the builtin & and | operators, code up your own & and | functions which handle an X state. I.e, an OR function would be :
Code:
In12 Out
0 0 = 0
0 1 = 1
0 X = X
1 0 = 1
1 1 = 1
1 X = 1
This makes it very similar to a normal OR function - at least one value must be 1 for the output to be 1 - but it adds the case where one input is 0 and the other is unknown to be equal to the unknown variable.