import java.util.ArrayList;
// predicate that allows at most one to be true
class atmostone extends node {
public atmostone( node l, node r ) {
left = l;
right = r;
}
public node klone() {
return new atmostone( left.klone(),right.klone() );
}
public ArrayList children() {
ArrayList ll;
ArrayList l = new ArrayList();
if ( left instanceof atmostone )
l.addAll( ( ( atmostone ) left ).children() );
else
l.add( left );
if ( right instanceof atmostone )
l.addAll( ( ( atmostone ) right ).children() );
else
l.add( right );
return l;
}
private node elem( Object[] o, int i ) {
return ( ( node ) o[i] ).klone();
}
private node makeAnd( Object[] o, int i, int j ) {
return new not( new and( elem( o,i ), elem( o,j ) ) );
}
/*
* x # y # z => (-x^-y^z v -x^y^-z v x^-y^-z )
*/
public node simplify() {
node n = null;
Object[] o = children().toArray();
int l = o.length;
if (l == 1)
return makeAnd( o, 0, 0 ); // returns true
for ( int i=0; i<l; i++ )
for ( int j=i+1; j<l; j++ )
if (n==null)
n = makeAnd(o,i,j);
else
n = new and( n, makeAnd( o,i,j ) );
return n.simplify();
}
public String toString() {
return "atmostone" +array2String( children().toArray(), "," );
}
public String cnf2String() {
// return parentheses around non-and arguments
//
System.out.println( " should not call " );
System.exit( 1 );
return null;
}
public node cnf() {
// rule: anything can sit immediately below ands
//
System.out.println( " should not call " );
System.exit( 1 );
return null;
}
}