diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,16 @@
 # Revision history for staversion
 
+## 0.2.0.0  -- 2017-05-14
+
+* [breaking change] `pvp` aggregator now does "trailing-zero
+  normalization". For example, it now assumes versions "2.2" and
+  "2.2.0.0" are practically the same (#2).
+* Add `pvp-major` aggregator, which is just an alias for `pvp`
+  aggregator.
+* Add `pvp-minor` aggregator, which is similar to `pvp-major` but it
+  uses minor versions for upper bounds (#2).
+
+
 ## 0.1.4.0  -- 2017-04-08
 
 * Add `--aggregate` option, which aggregates versions in different LTS resolvers.
diff --git a/src/Staversion/Internal/Aggregate.hs b/src/Staversion/Internal/Aggregate.hs
--- a/src/Staversion/Internal/Aggregate.hs
+++ b/src/Staversion/Internal/Aggregate.hs
@@ -12,7 +12,8 @@
          VersionRange,
          showVersionRange,
          aggOr,
-         aggPvp,
+         aggPvpMajor,
+         aggPvpMinor,
          -- * Utility
          groupAllPreservingOrderBy,
          -- * Low-level functions
@@ -29,6 +30,7 @@
 import Data.Maybe (fromJust)
 import Data.Monoid (mconcat, All(All))
 import Data.List (lookup)
+import qualified Data.List as List
 import Data.List.NonEmpty (NonEmpty(..))
 import qualified Data.List.NonEmpty as NL
 import Data.Text (unpack)
@@ -67,15 +69,40 @@
 aggOr :: Aggregator
 aggOr = foldr1 V.unionVersionRanges . fmap V.thisVersion . NL.nub . NL.sort
 
--- | Aggregate versions to the range that the versions cover in a
--- (strict) PVP sense.
-aggPvp :: Aggregator
-aggPvp = V.simplifyVersionRange . foldr1 V.unionVersionRanges . fmap toRange . NL.nub . NL.sort where
-  toRange v = fromJust $ fmap V.fromVersionIntervals $ V.mkVersionIntervals [(V.LowerBound v V.InclusiveBound, V.UpperBound vu V.ExclusiveBound)] where
-    vu = makeVersion $ case V.versionBranch v of
-      [] -> error "versionBranch must not be empty."
-      [x] -> [x, 0]
-      (x : y : _) -> [x, y + 1]
+-- | Aggregate versions to the range that the versions cover in a PVP
+-- sense. This aggregator sets the upper bound to a major version,
+-- which means it assumes major-version bump is not
+-- backward-compatible.
+aggPvpMajor :: Aggregator
+aggPvpMajor = aggPvpGeneral $ makeUpper where
+  makeUpper [] = error "version must not be empty."
+  makeUpper [x] = [x, 1] -- because [x] and [x,0] is equivalent
+  makeUpper (x : y : _) = [x, y + 1]
+
+-- | Aggregate versions to the range that versions cover in a PVP
+-- sense. This aggregator sets the upper bound to a minor version,
+-- which means it assumes minor-version bump is not
+-- backward-compatible.
+aggPvpMinor :: Aggregator
+aggPvpMinor = aggPvpGeneral $ makeUpper where
+  makeUpper [] = error "version must not be empty."
+  makeUpper [x] = [x, 0, 1]
+  makeUpper [x,y] = [x, y, 1]
+  makeUpper (x : y : z : _) = [x, y, z + 1]
+
+aggPvpGeneral :: ([Int] -> [Int]) -> Aggregator
+aggPvpGeneral makeUpper = V.simplifyVersionRange . foldr1 V.unionVersionRanges . fmap toRange . NL.nub . NL.sort where
+  toRange v = fromJust $ fmap V.fromVersionIntervals $ V.mkVersionIntervals [(V.LowerBound norm_v V.InclusiveBound, V.UpperBound vu V.ExclusiveBound)] where
+    norm_v = makeVersion $ normalizeTralingZeroes $ V.versionBranch v
+    vu = makeVersion $ makeUpper $ V.versionBranch norm_v
+
+normalizeTralingZeroes :: [Int] -> [Int]
+normalizeTralingZeroes [] = []
+normalizeTralingZeroes (head_v : rest) = head_v : (concat $ dropTrailingZeros $ List.group rest) where
+  dropTrailingZeros [] = []
+  dropTrailingZeros groups = if and $ map (== 0) $ last groups
+                             then init groups
+                             else groups
 
 -- | Aggregate 'Result's with the given 'Aggregator'. It first groups
 -- 'Result's based on its 'resultFor' field, and then each group is
diff --git a/src/Staversion/Internal/Command.hs b/src/Staversion/Internal/Command.hs
--- a/src/Staversion/Internal/Command.hs
+++ b/src/Staversion/Internal/Command.hs
@@ -123,10 +123,19 @@
 
 aggregators :: [AggregatorSpec]
 aggregators = [ AggregatorSpec Agg.aggOr "or" "concatenate versions with (||).",
-                AggregatorSpec Agg.aggPvp "pvp" ( "aggregate versions to a range that is supposed to be "
-                                                  ++ "compatible with the given versions "
-                                                  ++ "in terms of PVP (Package Versioning Policy.)"
-                                                )
+                AggregatorSpec Agg.aggPvpMajor "pvp-major"
+                ( "aggregate versions to a range that is supposed to be "
+                  ++ "compatible with the given versions "
+                  ++ "in terms of PVP (Package Versioning Policy.) "
+                  ++ "Major versions are used for upper bounds."
+                ),
+                AggregatorSpec Agg.aggPvpMajor "pvp" "alias for 'pvp-major'",
+                AggregatorSpec Agg.aggPvpMinor "pvp-minor"
+                ( "aggregate versions to a range that is supposed to be "
+                  ++ "compatible with the given versions "
+                  ++ "in terms of PVP. "
+                  ++ "Minor versions are used for upper bounds, i.e. this is stricter than 'pvp-major'."
+                )
               ]
 
 parseAggregator :: String -> Maybe Aggregator
diff --git a/staversion.cabal b/staversion.cabal
--- a/staversion.cabal
+++ b/staversion.cabal
@@ -1,5 +1,5 @@
 name:                   staversion
-version:                0.1.4.0
+version:                0.2.0.0
 author:                 Toshio Ito <debug.ito@gmail.com>
 maintainer:             Toshio Ito <debug.ito@gmail.com>
 license:                BSD3
@@ -47,7 +47,7 @@
                         Staversion.Internal.HTTP
   build-depends:        base >=4.8 && <4.10,
                         unordered-containers >=0.2.3 && <0.3,
-                        aeson >=0.8.0 && <1.2,
+                        aeson >=0.8.0 && <1.3,
                         text >=0.11.3 && <1.3,
                         bytestring >=0.10.0 && <0.11,
                         yaml >=0.8.3 && <0.9,
@@ -60,7 +60,7 @@
                         http-types >=0.8.6 && <0.10,
                         transformers >=0.3.0 && <0.6,
                         transformers-compat >=0.4.0 && <0.6,
-                        megaparsec >=4.2.0 && <5.3,
+                        megaparsec >=4.2.0 && <5.4,
                         semigroups >=0.18.0.1 && <0.19,
                         Cabal >=1.22.6.0 && <1.25,
                         pretty >=1.1.2.0 && <1.2,
diff --git a/test/Staversion/Internal/AggregateSpec.hs b/test/Staversion/Internal/AggregateSpec.hs
--- a/test/Staversion/Internal/AggregateSpec.hs
+++ b/test/Staversion/Internal/AggregateSpec.hs
@@ -13,7 +13,8 @@
   ( Aggregator,
     showVersionRange,
     aggOr,
-    aggPvp,
+    aggPvpMajor,
+    aggPvpMinor,
     aggregateResults,
     aggregatePackageVersions
   )
@@ -36,7 +37,8 @@
   spec_aggregateResults
   describe "Aggregators" $ do
     spec_or
-    spec_pvp
+    spec_pvpMajor
+    spec_pvpMinor
 
 vor :: V.VersionRange -> V.VersionRange -> V.VersionRange
 vor = V.unionVersionRanges
@@ -88,34 +90,102 @@
 vint vl vu = fromJust $ fmap V.fromVersionIntervals $ V.mkVersionIntervals [interval] where
   interval = (V.LowerBound (ver vl) V.InclusiveBound, V.UpperBound (ver vu) V.ExclusiveBound)
 
-spec_pvp :: Spec
-spec_pvp = describe "aggPvp" $ before (return aggPvp) $ do
+spec_pvpMajor :: Spec
+spec_pvpMajor = describe "aggPvpMajor" $ before (return aggPvpMajor) $ do
   testAgg [[1,2,0,7]] $ vint [1,2,0,7] [1,3]
-  testAgg [[1,2,0]] $ vint [1,2,0] [1,3]
+  testAgg [[1,2,3,0]] $ vint [1,2,3] [1,3] -- trailing-zero
+  testAgg [[1,2,0,0]] $ vint [1,2] [1,3] -- trailing-zeroes
+  testAgg [[1,2,10]] $ vint [1,2,10] [1,3]
+  testAgg [[1,2,0]] $ vint [1,2] [1,3]  -- trailing-zero
   testAgg [[1,2]] $ vint [1,2] [1,3]
-  testAgg [[1]] $ vint [1] [1,0]
-  testAgg [[1,2,0,0], [1,2,3,0]] $ vint [1,2,0,0] [1,3]
-  testAgg [[1,2,0,0], [1,2,0,0]] $ vint [1,2,0,0] [1,3]
-  testAgg [[1,2,0,0], [1,3]] $ vint [1,2,0,0] [1,4]
-  testAgg [[1,2,0,0], [1,3,0]] $ vors' [ vint [1,2,0,0] [1,3],
-                                         vint [1,3,0] [1,4]
+  testAgg [[1,0]] $ vint [1] [1,1] -- trailing-zero
+  testAgg [[1,0,0,0]] $ vint [1] [1,1] -- traling-zeroes
+  testAgg [[1]] $ vint [1] [1,1] -- because 1 and 1.0 are considered equivalent.
+  testAgg [[0]] $ vint [0] [0,1]
+  testAgg [[0,0]] $ vint [0] [0,1]
+  testAgg [[0,0,0]] $ vint [0] [0,1]
+  testAgg [[0,0,1]] $ vint [0,0,1] [0,1]
+  testAgg [[1,2,0,7], [1,2,3,0]] $ vint [1,2,0,7] [1,3]
+  testAgg [[1,2,0,7], [1,2,0,7]] $ vint [1,2,0,7] [1,3]
+  testAgg [[1,2,0,7], [1,3]] $ vint [1,2,0,7] [1,4]
+  testAgg [[1,2,0,7], [1,3,4]] $ vors' [ vint [1,2,0,7] [1,3],
+                                         vint [1,3,4] [1,4]
                                        ]
-  testAgg [[1,3,0], [1,2,0,0]] $ vors' [ vint [1,2,0,0] [1,3],
-                                         vint [1,3,0] [1,4]
+  testAgg [[1,2,0,7], [1,3,0]] $ vint [1,2,0,7] [1,4] -- trailing-zero
+  testAgg [[1,3,4], [1,2,0,7]] $ vors' [ vint [1,2,0,7] [1,3],
+                                         vint [1,3,4] [1,4]
                                        ]
-  testAgg [[1,2,0,0], [1,3,0,0]] $ vors' [ vint [1,2,0,0] [1,3],
-                                           vint [1,3,0,0] [1,4]
+  testAgg [[1,3,0], [1,2,0,7]] $ vint [1,2,0,7] [1,4]
+  testAgg [[1,2,0,7], [1,3,0,8]] $ vors' [ vint [1,2,0,7] [1,3],
+                                           vint [1,3,0,8] [1,4]
                                          ]
-  testAgg [[1,3,0,0], [1,2,0,0]] $ vors' [ vint [1,2,0,0] [1,3],
-                                           vint [1,3,0,0] [1,4]
+  testAgg [[1,2,0,0], [1,3,0,0]] $ vint [1,2] [1,4] -- trailing-zeroes
+  testAgg [[1,3,0,8], [1,2,0,7]] $ vors' [ vint [1,2,0,7] [1,3],
+                                           vint [1,3,0,8] [1,4]
                                          ]
-  testAgg [[1,2,0,0], [2]] $ vors' [ vint [1,2,0,0] [1,3],
-                                     vint [2] [2,0]
+  testAgg [[1,2,0,7], [2]] $ vors' [ vint [1,2,0,7] [1,3],
+                                     vint [2] [2,1]
                                    ]
-  testAgg [[2,2,0], [2,0], [3,5,0,1], [2,2,0,5]] $ vors' [ vint [2,0] [2,1],
-                                                           vint [2,2,0] [2,3],
+  testAgg [[2,2,0], [2,0], [3,5,0,1], [2,2,0,5]] $ vors' [ vint [2] [2,1],
+                                                           vint [2,2] [2,3],
                                                            vint [3,5,0,1] [3,6]
                                                          ]
+
+
+spec_pvpMinor :: Spec
+spec_pvpMinor = describe "aggPvpMinor" $ before (return aggPvpMinor) $ do
+  testAgg [[1,2,0,7]] $ vint [1,2,0,7] [1,2,1]
+  testAgg [[1,2,3,0]] $ vint [1,2,3] [1,2,4] -- trailing-zero
+  testAgg [[1,2,0,0]] $ vint [1,2] [1,2,1] -- trailing-zeroes
+  testAgg [[1,2,10]] $ vint [1,2,10] [1,2,11]
+  testAgg [[1,2,0]] $ vint [1,2] [1,2,1]  -- trailing-zero
+  testAgg [[1,2]] $ vint [1,2] [1,2,1]
+  testAgg [[1,0]] $ vint [1] [1,0,1] -- trailing-zero
+  testAgg [[1,0,0,0]] $ vint [1] [1,0,1] -- traling-zeroes
+  testAgg [[1]] $ vint [1] [1,0,1] -- because 1 and 1.0 are considered equivalent.
+  testAgg [[0]] $ vint [0] [0,0,1]
+  testAgg [[0,0]] $ vint [0] [0,0,1]
+  testAgg [[0,0,0]] $ vint [0] [0,0,1]
+  testAgg [[0,0,1]] $ vint [0,0,1] [0,0,2]
+  testAgg [[1,2,0,7], [1,2,3,0]] $ vors' [ vint [1,2,0,7] [1,2,1],
+                                           vint [1,2,3] [1,2,4]
+                                         ]
+  testAgg [[1,2,0,7], [1,2,0,7]] $ vint [1,2,0,7] [1,2,1]
+  testAgg [[1,2,0,7], [1,3]] $ vors' [ vint [1,2,0,7] [1,2,1],
+                                       vint [1,3] [1,3,1]
+                                     ]
+  testAgg [[1,2,0,7], [1,3,4]] $ vors' [ vint [1,2,0,7] [1,2,1],
+                                         vint [1,3,4] [1,3,5]
+                                       ]
+  testAgg [[1,2,0,7], [1,3,0]] $ vors' [ vint [1,2,0,7] [1,2,1],
+                                         vint [1,3] [1,3,1]
+                                       ]
+  testAgg [[1,3,4], [1,2,0,7]] $ vors' [ vint [1,2,0,7] [1,2,1],
+                                         vint [1,3,4] [1,3,5]
+                                       ]
+  testAgg [[1,3,0], [1,2,0,7]] $ vors' [ vint [1,2,0,7] [1,2,1],
+                                         vint [1,3] [1,3,1]
+                                       ]
+  testAgg [[1,2,0,7], [1,3,0,8]] $ vors' [ vint [1,2,0,7] [1,2,1],
+                                           vint [1,3,0,8] [1,3,1]
+                                         ]
+  testAgg [[1,2,0,0], [1,3,0,0]] $ vors' [ vint [1,2] [1,2,1],
+                                           vint [1,3] [1,3,1]
+                                         ]
+  testAgg [[1,3,0,8], [1,2,0,7]] $ vors' [ vint [1,2,0,7] [1,2,1],
+                                           vint [1,3,0,8] [1,3,1]
+                                         ]
+  testAgg [[1,2,0,7], [2]] $ vors' [ vint [1,2,0,7] [1,2,1],
+                                     vint [2] [2,0,1]
+                                   ]
+  testAgg [[2,2,0], [2,0], [3,5,0,1], [2,2,0,5]] $ vors' [ vint [2] [2,0,1],
+                                                           vint [2,2] [2,2,1],
+                                                           vint [3,5,0,1] [3,5,1]
+                                                         ]
+  testAgg [[1,2,2,4], [1,2,1,0], [1,2,0,4]] $ vors' [ vint [1,2,0,4] [1,2,2],
+                                                      vint [1,2,2,4] [1,2,3]
+                                                    ]
+
 
 testAgg :: [[Int]] -> V.VersionRange -> SpecWith Aggregator
 testAgg input expected = specify desc $ \agg -> agg input' `shouldBe` expected where
