// Randomly generate STRATCOMP instances as described in our KR98 paper
// (eite-etal-98a).
//
// Written by Gerald Pfeifer with most significant support by Wolfgang Faber.

#include <sys/types.h>
#include <unistd.h>

#include <stdlib.h>
#include <iostream.h>
#include <algorithm>
#include <vector>

const unsigned PRODUCERS = 2;

void controlled_by(
    vector<unsigned> u,
    unsigned  c1,
    unsigned  c2,
    unsigned  c3 )
    {
    cout << "controlled_by(" 
         << u[0] << ','
         << u[c1] << ','
         << u[c2] << ','
         << u[c3] << ")."
         << endl;
    }

bool fiftyfifty()
    {
    return rand()%2 == 0;
    }
    
int main(int argc, char *argv[])
    {
    if( argc != 3 )
        {
        cerr << "usage: " << argv[0] << "  #companies #products/#companies" << endl;
        return -1;
        } 


    srand(getpid());

    const unsigned n=atoi(argv[1]);
    const unsigned PRODUCTS_DIV_COMPANIES = atoi(argv[2]);

    if( n < 6 )
        {
        cerr << argv[0] << ": at least 6 companies required." << endl;
        return 1;
        }

    // n companies
    for(unsigned i=1; i <= n; i++)
        {
        unsigned controllers = (rand() % 5) + 1; // 1..5 controllers
        
        vector<unsigned> c;
        
        // dummy to avoid that a company controls itself
        c.push_back(i); 
        
        for(unsigned j=1; j <= controllers; j++)
            {
            // guess controllers many distinct numbers in [1..n]
            unsigned guess;
            do
                {
                guess= (rand() % n) + 1;
                }     
            while( find(c.begin(),c.end(),guess) != c.end() );

            c.push_back(guess);
            }

        switch( controllers )
            {
            case 1:
                controlled_by(c,1,1,1);
                break;
            case 2:
                controlled_by(c,1,2,2);
                break;
            case 3:
                if( fiftyfifty() )
                    controlled_by(c,1,2,3);
                else
                    {
                    controlled_by(c,1,2,2);
                    controlled_by(c,1,3,3);
                    }
                break;
            case 4:
                if( fiftyfifty() )
                    {
                    controlled_by(c,1,2,2);
                    controlled_by(c,1,3,4);
                    }
                else
                    {
                    controlled_by(c,1,2,3);
                    controlled_by(c,1,2,4);
                    }
                break;
            case 5:
                controlled_by(c,1,2,3);
                controlled_by(c,1,4,5);
                break;
            default:
                abort();
            }
        }

    for(unsigned i=1; i <= n*PRODUCTS_DIV_COMPANIES; i++)
        {
        cout << "produced_by(p" << i << ", ";

        for(unsigned j=1; j <= PRODUCERS; j++)
            {
            cout << (rand() % n) + 1;

            if( j < PRODUCERS )
     	        cout << ",";
            }
            
        cout << ")." << endl;            
        }
	     

    return 0;
    }

