{-# LANGUAGE GADTs, OverloadedStrings, QuasiQuotes #-} {-# OPTIONS_GHC -fno-warn-type-defaults #-} module SingularBench where import Algebra.Algorithms.Groebner.Monomorphic import Algebra.Internal import Algebra.Ring.Polynomial (Coefficient (..), ProductOrder (..), ToWeightVector (..), WeightOrder (..), WeightProxy (..), showRational) import Algebra.Ring.Polynomial.Monomorphic import Control.Arrow import Data.List import qualified Data.Map as M import Data.Monoid import Data.Singletons import Data.Type.Natural import System.Process formatPoly :: Polynomial (Fraction Integer) -> String formatPoly (Polynomial dic) = intercalate "+" $ map (uncurry formatTerm) $ M.toList dic formatTerm :: M.Map Variable Integer -> (Fraction Integer) -> String formatTerm k v | M.null k = showCoeff $ showRational v | otherwise = concat ["(", showCoeff $ showRational v, ")*", formatMonom k] showCoeff :: Coefficient -> String showCoeff Zero = "0" showCoeff (Negative str) = '-':str showCoeff (Positive str) = str showCoeff Eps = "1" formatMonom :: Monomial -> String formatMonom = intercalate "*" . map (uncurry (++) <<< show *** ('^':).show) . M.toList formatIdeal :: [Polynomial (Fraction Integer)] -> String formatIdeal = intercalate ", " . map formatPoly class IsMonomialOrder ord => SingularRep ord where singularRep :: ord -> String instance SingularRep Lex where singularRep _ = "lp" instance SingularRep Grlex where singularRep _ = "Dp" instance SingularRep Grevlex where singularRep _ = "dp" instance (SingI n, SingularRep o1, SingularRep o2) => SingularRep (ProductOrder n o1 o2) where singularRep (ProductOrder n o1 o2) = concat ["(", singularRep o1, "(", show (sNatToInt n), ")," , singularRep o2, ")" ] instance (ToWeightVector vec, SingularRep ord) => SingularRep (WeightOrder vec ord) where singularRep (WeightOrder vec ord) = concat ["(a(", init $ tail $ show $ tovec vec, ")," , singularRep ord, ")" ] where tovec :: WeightProxy v -> [Int] tovec NilWeight = [] tovec (ConsWeight n ns) = sNatToInt n : tovec ns type Ideal = [Polynomial (Fraction Integer)] skeleton :: SingularRep ord => ord -> [Polynomial (Fraction Integer)] -> String skeleton ord ideal = unlines [ "LIB \"poly.lib\";" , concat ["ring R = 0,(" ,intercalate "," (map show $ nub $ sort $ concatMap buildVarsList ideal) , ")," , singularRep ord, ";"] , "ideal I =" <> formatIdeal ideal <> ";" , "std(I);" , "quit;" ] singularWith :: SingularRep ord => ord -> Ideal -> IO String singularWith = (readProcess "singular" [] .) . skeleton