| {-# LANGUAGE StrictData #-} |
|
|
| |
| |
| |
| |
|
|
| module LiquidLean.Jacobian.MoraLocal |
| ( weakNF |
| , groebnerBasisLocal |
| , countStandardMonomials |
| , dividesLocal |
| ) where |
|
|
| import LiquidLean.Jacobian.Theorem3Kernel |
| import qualified Data.Map.Strict as Map |
|
|
| |
| |
| |
|
|
| weakNF :: [Polynomial] -> Polynomial -> Polynomial |
| weakNF basis f = go f |
| where |
| go h | isZeroPoly h = h |
| | otherwise = case findReducer basis h of |
| Nothing -> h |
| Just (g, coeff, lmDiff) -> |
| go (subPoly h (scalePoly coeff (mulPoly g (uncurry monomial lmDiff)))) |
|
|
| findReducer :: [Polynomial] -> Polynomial -> Maybe (Polynomial, Rational, (Int, Int)) |
| findReducer [] _ = Nothing |
| findReducer (g:gs) h = |
| let (ltH, lmH) = leadingTermLocal h |
| (ltG, lmG) = leadingTermLocal g |
| in if dividesLocal lmG lmH |
| then Just (g, ltH / ltG, monomialDiff lmH lmG) |
| else findReducer gs h |
|
|
| |
| dividesLocal :: LocalMonomial -> LocalMonomial -> Bool |
| dividesLocal (LM u1 x1) (LM u2 x2) = u1 <= u2 && x1 <= x2 |
|
|
| monomialDiff :: LocalMonomial -> LocalMonomial -> (Int, Int) |
| monomialDiff (LM u1 x1) (LM u2 x2) = (u2 - u1, x2 - x1) |
|
|
| |
| |
| |
|
|
| groebnerBasisLocal :: [Polynomial] -> Thermal [Polynomial] |
| groebnerBasisLocal fs = do |
| emitEnergy phiDecay |
| let tc0 = map leadingForm fs |
| moraLoop tc0 fs [] |
| where |
| leadingForm p = |
| let (c, LM u x) = leadingTermLocal p |
| in if c == 0 then zeroPoly else scalePoly c (monomial u x) |
|
|
| moraLoop :: [Polynomial] -> [Polynomial] -> [Polynomial] -> Thermal [Polynomial] |
| moraLoop tangentCone [] acc = pure (reverse acc ++ tangentCone) |
| moraLoop tangentCone (f:fs) acc = do |
| emitEnergy phiDecay |
| let nf = weakNF tangentCone f |
| if isZeroPoly nf |
| then moraLoop tangentCone fs acc |
| else do |
| let newTC = leadingForm nf : tangentCone |
| moraLoop newTC fs (nf : acc) |
|
|
| |
| |
| |
|
|
| countStandardMonomials :: [Polynomial] -> Int |
| countStandardMonomials gb = |
| let lms = map (snd . leadingTermLocal) gb |
| maxDeg = if null lms then 1 else 2 * maximum [lmU lm + lmX lm | lm <- lms] |
| isStd (LM u x) = all (\(LM a b) -> a > u || b > x) lms |
| in length [ () | u <- [0..maxDeg], x <- [0..maxDeg], u+x <= maxDeg, isStd (LM u x) ] |
|
|