/*
 * app_generictropicalspecialization.cpp
 *
 *  Created on: Nov 20, 2025
 *      Author: anders
 */

#include "parser.h"
#include "printer.h"
#include "polynomial.h"
#include "buchberger.h"
#include "wallideal.h"
#include "termorder.h"
#include "gfanapplication.h"
#include "tropical2.h"
#include "matrix.h"
#include "field_rationalfunctions.h"
#include "field_rationalfunctions2.h"

class GenericTropicalSpecialisationApplication : public GFanApplication
{
	SimpleOption optionMinT;
	SimpleOption optionNonGeneric;
public:
	bool includeInDefaultInstallation()
	{
		return false;
	}
  const char *helpText()
  {
    return "This program takes a set of polynomials in a ring k[m_1,...,m_N,x_1,...,x_n] and a choice of valuation for m_1,...,m_n. For each polynomial it is determined which tropical hypersurface would appear if m_1,...,m_n are specialized to values with these valuations - or rather a defining polynomial polynomial is produced (its tropicalisation defines the hypersurface) with coefficients being functions in t. If the coefficients of the values are chosen generically this procedure is always successful. On the other hand if the first coefficients of the values could be algebraically dependent, the process might fail, since cancellations might make it impossible to determine valuations of coefficients after substitution. By using the option --nongeneric the polynomials having this problem will be filtered out.\n";
  }
  GenericTropicalSpecialisationApplication():
	  optionMinT("--mint","In a field with parameter t this option decides if maximal or minimal degrees of t determine the valuation."),
	  optionNonGeneric("--nongeneric","Remove polynomials from the output if the tropical hypersurface cannot trivially be determined without the assumption that the first coefficients of the specialisation values are generic.")
  {
    registerOptions();
  }

  const char *name()
  {
    return "_generictropicalspecialization";
  }

  int main()
  {
//	  debug<<"IF COEFFICIENTS ARE NOT SINGLE TERMS THE TROPICALISATION WILL DEPEND ON WHICH CONVENTION IS USED -- AT THE MOMENT THIS IS MAX FOR COEFFICIENTS\n";
	  FileParser P(Stdin);

    auto valuations=P.parseIntegerVector();
    PolynomialSet g=P.parsePolynomialSetWithRing();

    auto g2=makeVariablesParameters(makeVariablesParameters(g.getRing(),valuations.size()),g);

    AsciiPrinter(Stderr).printPolynomialRing(g2.getRing());
    AsciiPrinter(Stderr).printPolynomialSet(g2);

    auto CoefRing=FieldRationalFunctions(g.getRing().getField(),string("t"));
    PolynomialRing r(CoefRing,g2.getRing().getVariableNames());

    int signFlip=1;
    if(optionMinT.getValue())
    {
    	valuations=-valuations;
    	signFlip=-1;
    }

    PolynomialSet g3(r);
    for(auto const &f:g2)
    {
    	Polynomial F(r);
    	bool polyOK=true;
    	for(TermMap::const_iterator i=f.terms.begin();i!=f.terms.end();i++)
    	{
        	auto p=getNumeratorAndDenominatorOfRationalFunction2(i->second).first;
        	if(!initialForm(p,valuations).isMonomial())polyOK=false;
        	int exp=signFlip*p.degree(valuations);
    		Polynomial tt=Polynomial(Term(CoefRing.exponent(exp),Monomial(r,i->first.exponent)));
    		F=F+tt;
    	}
    	if(polyOK || optionNonGeneric.getValue()==false)
    		g3.push_back(F);
    }
    pout<<g3.getRing()<<g3;

    return 0;
  }
};

static GenericTropicalSpecialisationApplication theApplication;
