groupBy function which groups non-adjacent elements











up vote
2
down vote

favorite












The groupBy function groups the elements of a list when they are equal according to a user-defined predicate and when they are adjacent in the list. Is there a function for grouping elements without taking care of the adjacency?



I deal with polynomials of three variables. Here is an example of such a polynomial written as a sum of monomials:



p = (M (Monomial {coefficient = 1.0, powers = (1,0,0)}) :+: M (Monomial {coefficient = 1.0, powers = (0,1,0)})) :+: M (Monomial {coefficient = 1.0, powers = (1,0,0)})


That means that p = 1.0 * x^1y^0z^0 + 1.0 * x^0y^1z^0 + 1.0 * x^1y^0z^0. The first term and the third term are summable: they have the same powers and then we can add them and get 2.0 * x^1y^0z^0. My goal is to do this addition, in order to simplify p.



I have a function which converts such a p to the list of the summed monomials:



>> toListOfMonomials p
[M (Monomial {coefficient = 1.0, powers = (1,0,0)}),M (Monomial {coefficient = 1.0, powers = (0,1,0)}),M (Monomial {coefficient = 1.0, powers = (1,0,0)})]


I want to group the monomials which have the same powers. If I do



groupBy ((==) `on` getPowers)
(toListOfMonomials p)


then the two M (Monomial {coefficient = 1.0, powers = (1,0,0)}) are not grouped because they are not adjacent.



A solution consists in sorting the list according to the powers before using groupBy. In this way, two (or more) monomials having the same powers are adjacent in the sorted list. To define an order on the powers (powers is a triplet of integers), I firstly define a Cantor pairing function:



cantorPairing :: (Int, Int) -> Int
cantorPairing (k1,k2) = (k1+k2)*(k1+k2+1) + 2*k2

cantorPairing' :: (Int, Int, Int) -> Int
cantorPairing' (k1,k2,k3) = cantorPairing(cantorPairing(k1,k2),k3)


then I can compare two powers by comparing their values under the Cantor pairing function:



groupBy ((==) `on` getPowers)
(sortBy (compare `on` (cantorPairing' . getPowers)) (toListOfMonomials p))


This gives the desired result: with this result I can easily sum the two monomials having the same powers.



But that looks heavy, doesn't it? Isn't there a groupBy function which groups also non-adjacent elements? Otherwise, is there a more rapid way to achieve the desired result?










share|improve this question






















  • I would move the sorting into toListOfMonomials itself. An addition function that can combine like terms immediately might be preferable to a separate :+: constructor.
    – chepner
    Nov 19 at 15:27












  • @chepner I agree. Good point. Thanks!
    – Stéphane Laurent
    Nov 19 at 15:31






  • 1




    I generally do this sort of thing by going through Data.Map. It's about equally verbose, but sometimes it's useful that (cantorPairing' . getPowers) get called n times instead of O(n log n) times.
    – bergey
    Nov 19 at 15:42






  • 2




    This type of question seems to come up regularly. Like @bergey I usually use Data.Map for the grouping step. Here's an example: stackoverflow.com/a/52535999/126014
    – Mark Seemann
    Nov 19 at 19:47















up vote
2
down vote

favorite












The groupBy function groups the elements of a list when they are equal according to a user-defined predicate and when they are adjacent in the list. Is there a function for grouping elements without taking care of the adjacency?



I deal with polynomials of three variables. Here is an example of such a polynomial written as a sum of monomials:



p = (M (Monomial {coefficient = 1.0, powers = (1,0,0)}) :+: M (Monomial {coefficient = 1.0, powers = (0,1,0)})) :+: M (Monomial {coefficient = 1.0, powers = (1,0,0)})


That means that p = 1.0 * x^1y^0z^0 + 1.0 * x^0y^1z^0 + 1.0 * x^1y^0z^0. The first term and the third term are summable: they have the same powers and then we can add them and get 2.0 * x^1y^0z^0. My goal is to do this addition, in order to simplify p.



I have a function which converts such a p to the list of the summed monomials:



>> toListOfMonomials p
[M (Monomial {coefficient = 1.0, powers = (1,0,0)}),M (Monomial {coefficient = 1.0, powers = (0,1,0)}),M (Monomial {coefficient = 1.0, powers = (1,0,0)})]


I want to group the monomials which have the same powers. If I do



groupBy ((==) `on` getPowers)
(toListOfMonomials p)


then the two M (Monomial {coefficient = 1.0, powers = (1,0,0)}) are not grouped because they are not adjacent.



A solution consists in sorting the list according to the powers before using groupBy. In this way, two (or more) monomials having the same powers are adjacent in the sorted list. To define an order on the powers (powers is a triplet of integers), I firstly define a Cantor pairing function:



cantorPairing :: (Int, Int) -> Int
cantorPairing (k1,k2) = (k1+k2)*(k1+k2+1) + 2*k2

cantorPairing' :: (Int, Int, Int) -> Int
cantorPairing' (k1,k2,k3) = cantorPairing(cantorPairing(k1,k2),k3)


then I can compare two powers by comparing their values under the Cantor pairing function:



groupBy ((==) `on` getPowers)
(sortBy (compare `on` (cantorPairing' . getPowers)) (toListOfMonomials p))


This gives the desired result: with this result I can easily sum the two monomials having the same powers.



But that looks heavy, doesn't it? Isn't there a groupBy function which groups also non-adjacent elements? Otherwise, is there a more rapid way to achieve the desired result?










share|improve this question






















  • I would move the sorting into toListOfMonomials itself. An addition function that can combine like terms immediately might be preferable to a separate :+: constructor.
    – chepner
    Nov 19 at 15:27












  • @chepner I agree. Good point. Thanks!
    – Stéphane Laurent
    Nov 19 at 15:31






  • 1




    I generally do this sort of thing by going through Data.Map. It's about equally verbose, but sometimes it's useful that (cantorPairing' . getPowers) get called n times instead of O(n log n) times.
    – bergey
    Nov 19 at 15:42






  • 2




    This type of question seems to come up regularly. Like @bergey I usually use Data.Map for the grouping step. Here's an example: stackoverflow.com/a/52535999/126014
    – Mark Seemann
    Nov 19 at 19:47













up vote
2
down vote

favorite









up vote
2
down vote

favorite











The groupBy function groups the elements of a list when they are equal according to a user-defined predicate and when they are adjacent in the list. Is there a function for grouping elements without taking care of the adjacency?



I deal with polynomials of three variables. Here is an example of such a polynomial written as a sum of monomials:



p = (M (Monomial {coefficient = 1.0, powers = (1,0,0)}) :+: M (Monomial {coefficient = 1.0, powers = (0,1,0)})) :+: M (Monomial {coefficient = 1.0, powers = (1,0,0)})


That means that p = 1.0 * x^1y^0z^0 + 1.0 * x^0y^1z^0 + 1.0 * x^1y^0z^0. The first term and the third term are summable: they have the same powers and then we can add them and get 2.0 * x^1y^0z^0. My goal is to do this addition, in order to simplify p.



I have a function which converts such a p to the list of the summed monomials:



>> toListOfMonomials p
[M (Monomial {coefficient = 1.0, powers = (1,0,0)}),M (Monomial {coefficient = 1.0, powers = (0,1,0)}),M (Monomial {coefficient = 1.0, powers = (1,0,0)})]


I want to group the monomials which have the same powers. If I do



groupBy ((==) `on` getPowers)
(toListOfMonomials p)


then the two M (Monomial {coefficient = 1.0, powers = (1,0,0)}) are not grouped because they are not adjacent.



A solution consists in sorting the list according to the powers before using groupBy. In this way, two (or more) monomials having the same powers are adjacent in the sorted list. To define an order on the powers (powers is a triplet of integers), I firstly define a Cantor pairing function:



cantorPairing :: (Int, Int) -> Int
cantorPairing (k1,k2) = (k1+k2)*(k1+k2+1) + 2*k2

cantorPairing' :: (Int, Int, Int) -> Int
cantorPairing' (k1,k2,k3) = cantorPairing(cantorPairing(k1,k2),k3)


then I can compare two powers by comparing their values under the Cantor pairing function:



groupBy ((==) `on` getPowers)
(sortBy (compare `on` (cantorPairing' . getPowers)) (toListOfMonomials p))


This gives the desired result: with this result I can easily sum the two monomials having the same powers.



But that looks heavy, doesn't it? Isn't there a groupBy function which groups also non-adjacent elements? Otherwise, is there a more rapid way to achieve the desired result?










share|improve this question













The groupBy function groups the elements of a list when they are equal according to a user-defined predicate and when they are adjacent in the list. Is there a function for grouping elements without taking care of the adjacency?



I deal with polynomials of three variables. Here is an example of such a polynomial written as a sum of monomials:



p = (M (Monomial {coefficient = 1.0, powers = (1,0,0)}) :+: M (Monomial {coefficient = 1.0, powers = (0,1,0)})) :+: M (Monomial {coefficient = 1.0, powers = (1,0,0)})


That means that p = 1.0 * x^1y^0z^0 + 1.0 * x^0y^1z^0 + 1.0 * x^1y^0z^0. The first term and the third term are summable: they have the same powers and then we can add them and get 2.0 * x^1y^0z^0. My goal is to do this addition, in order to simplify p.



I have a function which converts such a p to the list of the summed monomials:



>> toListOfMonomials p
[M (Monomial {coefficient = 1.0, powers = (1,0,0)}),M (Monomial {coefficient = 1.0, powers = (0,1,0)}),M (Monomial {coefficient = 1.0, powers = (1,0,0)})]


I want to group the monomials which have the same powers. If I do



groupBy ((==) `on` getPowers)
(toListOfMonomials p)


then the two M (Monomial {coefficient = 1.0, powers = (1,0,0)}) are not grouped because they are not adjacent.



A solution consists in sorting the list according to the powers before using groupBy. In this way, two (or more) monomials having the same powers are adjacent in the sorted list. To define an order on the powers (powers is a triplet of integers), I firstly define a Cantor pairing function:



cantorPairing :: (Int, Int) -> Int
cantorPairing (k1,k2) = (k1+k2)*(k1+k2+1) + 2*k2

cantorPairing' :: (Int, Int, Int) -> Int
cantorPairing' (k1,k2,k3) = cantorPairing(cantorPairing(k1,k2),k3)


then I can compare two powers by comparing their values under the Cantor pairing function:



groupBy ((==) `on` getPowers)
(sortBy (compare `on` (cantorPairing' . getPowers)) (toListOfMonomials p))


This gives the desired result: with this result I can easily sum the two monomials having the same powers.



But that looks heavy, doesn't it? Isn't there a groupBy function which groups also non-adjacent elements? Otherwise, is there a more rapid way to achieve the desired result?







haskell grouping






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 at 15:13









Stéphane Laurent

12.2k65291




12.2k65291












  • I would move the sorting into toListOfMonomials itself. An addition function that can combine like terms immediately might be preferable to a separate :+: constructor.
    – chepner
    Nov 19 at 15:27












  • @chepner I agree. Good point. Thanks!
    – Stéphane Laurent
    Nov 19 at 15:31






  • 1




    I generally do this sort of thing by going through Data.Map. It's about equally verbose, but sometimes it's useful that (cantorPairing' . getPowers) get called n times instead of O(n log n) times.
    – bergey
    Nov 19 at 15:42






  • 2




    This type of question seems to come up regularly. Like @bergey I usually use Data.Map for the grouping step. Here's an example: stackoverflow.com/a/52535999/126014
    – Mark Seemann
    Nov 19 at 19:47


















  • I would move the sorting into toListOfMonomials itself. An addition function that can combine like terms immediately might be preferable to a separate :+: constructor.
    – chepner
    Nov 19 at 15:27












  • @chepner I agree. Good point. Thanks!
    – Stéphane Laurent
    Nov 19 at 15:31






  • 1




    I generally do this sort of thing by going through Data.Map. It's about equally verbose, but sometimes it's useful that (cantorPairing' . getPowers) get called n times instead of O(n log n) times.
    – bergey
    Nov 19 at 15:42






  • 2




    This type of question seems to come up regularly. Like @bergey I usually use Data.Map for the grouping step. Here's an example: stackoverflow.com/a/52535999/126014
    – Mark Seemann
    Nov 19 at 19:47
















I would move the sorting into toListOfMonomials itself. An addition function that can combine like terms immediately might be preferable to a separate :+: constructor.
– chepner
Nov 19 at 15:27






I would move the sorting into toListOfMonomials itself. An addition function that can combine like terms immediately might be preferable to a separate :+: constructor.
– chepner
Nov 19 at 15:27














@chepner I agree. Good point. Thanks!
– Stéphane Laurent
Nov 19 at 15:31




@chepner I agree. Good point. Thanks!
– Stéphane Laurent
Nov 19 at 15:31




1




1




I generally do this sort of thing by going through Data.Map. It's about equally verbose, but sometimes it's useful that (cantorPairing' . getPowers) get called n times instead of O(n log n) times.
– bergey
Nov 19 at 15:42




I generally do this sort of thing by going through Data.Map. It's about equally verbose, but sometimes it's useful that (cantorPairing' . getPowers) get called n times instead of O(n log n) times.
– bergey
Nov 19 at 15:42




2




2




This type of question seems to come up regularly. Like @bergey I usually use Data.Map for the grouping step. Here's an example: stackoverflow.com/a/52535999/126014
– Mark Seemann
Nov 19 at 19:47




This type of question seems to come up regularly. Like @bergey I usually use Data.Map for the grouping step. Here's an example: stackoverflow.com/a/52535999/126014
– Mark Seemann
Nov 19 at 19:47












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










For now I cannot imagine general groupBy function that would work faster than O(n^2) time, but you may use something like this



groupBy2 :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy2 = go where
go acc comp = acc
go acc comp (h:t) =
let (hs, nohs) = partition (comp h) t
in go ((h:hs):acc) comp nohs


It works exactly like regular groupBy, but it joins non-adjacent element classes.



However, if you are going to use on function the problem becomes a bit simplier, as we may use it's result as key for a map:



import qualified Data.Map as M

groupOn :: (Ord b) => (a -> b) -> [a] -> [[a]]
groupOn f =
let unpack = fmap snd . M.toList
fld m a = case M.lookup (f a) m of
Nothing -> M.insert (f a) [a] m
Just as -> M.insert (f a) (a:as) m
in unpack . foldl fld M.empty


This is more efficient equivalent of



groupOn' f = groupBy2 ((==) `on` f)


(modulo ordering)



And btw – triplets and pairs already have defined Ord instance, you may compare them just like Ints






share|improve this answer























  • Thanks. I have generalized my code to deal with polynomials having an arbitrary number of variables, and now the powers are lists, not triplets. But lists with the same length also have an Ord instance (I didn't know), therefore there's no need of using a Cantor pairing. Haskell is very fun to program such things.
    – Stéphane Laurent
    Nov 21 at 12:16










  • Lists' Ord instance does not care about length. If elements match, the longer is greater.
    – radrow
    Nov 21 at 19:31











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53377577%2fgroupby-function-which-groups-non-adjacent-elements%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote



accepted










For now I cannot imagine general groupBy function that would work faster than O(n^2) time, but you may use something like this



groupBy2 :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy2 = go where
go acc comp = acc
go acc comp (h:t) =
let (hs, nohs) = partition (comp h) t
in go ((h:hs):acc) comp nohs


It works exactly like regular groupBy, but it joins non-adjacent element classes.



However, if you are going to use on function the problem becomes a bit simplier, as we may use it's result as key for a map:



import qualified Data.Map as M

groupOn :: (Ord b) => (a -> b) -> [a] -> [[a]]
groupOn f =
let unpack = fmap snd . M.toList
fld m a = case M.lookup (f a) m of
Nothing -> M.insert (f a) [a] m
Just as -> M.insert (f a) (a:as) m
in unpack . foldl fld M.empty


This is more efficient equivalent of



groupOn' f = groupBy2 ((==) `on` f)


(modulo ordering)



And btw – triplets and pairs already have defined Ord instance, you may compare them just like Ints






share|improve this answer























  • Thanks. I have generalized my code to deal with polynomials having an arbitrary number of variables, and now the powers are lists, not triplets. But lists with the same length also have an Ord instance (I didn't know), therefore there's no need of using a Cantor pairing. Haskell is very fun to program such things.
    – Stéphane Laurent
    Nov 21 at 12:16










  • Lists' Ord instance does not care about length. If elements match, the longer is greater.
    – radrow
    Nov 21 at 19:31















up vote
1
down vote



accepted










For now I cannot imagine general groupBy function that would work faster than O(n^2) time, but you may use something like this



groupBy2 :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy2 = go where
go acc comp = acc
go acc comp (h:t) =
let (hs, nohs) = partition (comp h) t
in go ((h:hs):acc) comp nohs


It works exactly like regular groupBy, but it joins non-adjacent element classes.



However, if you are going to use on function the problem becomes a bit simplier, as we may use it's result as key for a map:



import qualified Data.Map as M

groupOn :: (Ord b) => (a -> b) -> [a] -> [[a]]
groupOn f =
let unpack = fmap snd . M.toList
fld m a = case M.lookup (f a) m of
Nothing -> M.insert (f a) [a] m
Just as -> M.insert (f a) (a:as) m
in unpack . foldl fld M.empty


This is more efficient equivalent of



groupOn' f = groupBy2 ((==) `on` f)


(modulo ordering)



And btw – triplets and pairs already have defined Ord instance, you may compare them just like Ints






share|improve this answer























  • Thanks. I have generalized my code to deal with polynomials having an arbitrary number of variables, and now the powers are lists, not triplets. But lists with the same length also have an Ord instance (I didn't know), therefore there's no need of using a Cantor pairing. Haskell is very fun to program such things.
    – Stéphane Laurent
    Nov 21 at 12:16










  • Lists' Ord instance does not care about length. If elements match, the longer is greater.
    – radrow
    Nov 21 at 19:31













up vote
1
down vote



accepted







up vote
1
down vote



accepted






For now I cannot imagine general groupBy function that would work faster than O(n^2) time, but you may use something like this



groupBy2 :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy2 = go where
go acc comp = acc
go acc comp (h:t) =
let (hs, nohs) = partition (comp h) t
in go ((h:hs):acc) comp nohs


It works exactly like regular groupBy, but it joins non-adjacent element classes.



However, if you are going to use on function the problem becomes a bit simplier, as we may use it's result as key for a map:



import qualified Data.Map as M

groupOn :: (Ord b) => (a -> b) -> [a] -> [[a]]
groupOn f =
let unpack = fmap snd . M.toList
fld m a = case M.lookup (f a) m of
Nothing -> M.insert (f a) [a] m
Just as -> M.insert (f a) (a:as) m
in unpack . foldl fld M.empty


This is more efficient equivalent of



groupOn' f = groupBy2 ((==) `on` f)


(modulo ordering)



And btw – triplets and pairs already have defined Ord instance, you may compare them just like Ints






share|improve this answer














For now I cannot imagine general groupBy function that would work faster than O(n^2) time, but you may use something like this



groupBy2 :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy2 = go where
go acc comp = acc
go acc comp (h:t) =
let (hs, nohs) = partition (comp h) t
in go ((h:hs):acc) comp nohs


It works exactly like regular groupBy, but it joins non-adjacent element classes.



However, if you are going to use on function the problem becomes a bit simplier, as we may use it's result as key for a map:



import qualified Data.Map as M

groupOn :: (Ord b) => (a -> b) -> [a] -> [[a]]
groupOn f =
let unpack = fmap snd . M.toList
fld m a = case M.lookup (f a) m of
Nothing -> M.insert (f a) [a] m
Just as -> M.insert (f a) (a:as) m
in unpack . foldl fld M.empty


This is more efficient equivalent of



groupOn' f = groupBy2 ((==) `on` f)


(modulo ordering)



And btw – triplets and pairs already have defined Ord instance, you may compare them just like Ints







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 20 at 23:28

























answered Nov 20 at 23:20









radrow

535414




535414












  • Thanks. I have generalized my code to deal with polynomials having an arbitrary number of variables, and now the powers are lists, not triplets. But lists with the same length also have an Ord instance (I didn't know), therefore there's no need of using a Cantor pairing. Haskell is very fun to program such things.
    – Stéphane Laurent
    Nov 21 at 12:16










  • Lists' Ord instance does not care about length. If elements match, the longer is greater.
    – radrow
    Nov 21 at 19:31


















  • Thanks. I have generalized my code to deal with polynomials having an arbitrary number of variables, and now the powers are lists, not triplets. But lists with the same length also have an Ord instance (I didn't know), therefore there's no need of using a Cantor pairing. Haskell is very fun to program such things.
    – Stéphane Laurent
    Nov 21 at 12:16










  • Lists' Ord instance does not care about length. If elements match, the longer is greater.
    – radrow
    Nov 21 at 19:31
















Thanks. I have generalized my code to deal with polynomials having an arbitrary number of variables, and now the powers are lists, not triplets. But lists with the same length also have an Ord instance (I didn't know), therefore there's no need of using a Cantor pairing. Haskell is very fun to program such things.
– Stéphane Laurent
Nov 21 at 12:16




Thanks. I have generalized my code to deal with polynomials having an arbitrary number of variables, and now the powers are lists, not triplets. But lists with the same length also have an Ord instance (I didn't know), therefore there's no need of using a Cantor pairing. Haskell is very fun to program such things.
– Stéphane Laurent
Nov 21 at 12:16












Lists' Ord instance does not care about length. If elements match, the longer is greater.
– radrow
Nov 21 at 19:31




Lists' Ord instance does not care about length. If elements match, the longer is greater.
– radrow
Nov 21 at 19:31


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53377577%2fgroupby-function-which-groups-non-adjacent-elements%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

"Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

Alcedinidae

Origin of the phrase “under your belt”?