Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
majorityJudgment
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
delanoe
majorityJudgment
Commits
b3efeba6
Commit
b3efeba6
authored
Dec 18, 2018
by
Alexandre Delanoë
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
with example, discussion/feedbacks requested.
parent
9acfa99c
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
89 additions
and
17 deletions
+89
-17
README.md
README.md
+3
-1
Main.hs
app/Main.hs
+1
-1
package.yaml
package.yaml
+1
-0
Lib.hs
src/Lib.hs
+84
-15
No files found.
README.md
View file @
b3efeba6
# majorityJudgment
# Majority Judgment Haskell Implementation
app/Main.hs
View file @
b3efeba6
...
...
@@ -3,4 +3,4 @@ module Main where
import
Lib
main
::
IO
()
main
=
someFunc
main
=
undefined
package.yaml
View file @
b3efeba6
...
...
@@ -24,6 +24,7 @@ dependencies:
-
containers
-
text
-
safe
-
extra
library
:
source-dirs
:
src
...
...
src/Lib.hs
View file @
b3efeba6
{-|
Module : Majority Vote
Description : Majority vote
Copyright : (c) CNRS, 2018-Present
License : AGPL + CECILL v3
Maintainer : alexandre+dev@delanoe.org
Stability : experimental
Portability : POSIX
-}
{-# LANGUAGE OverloadedStrings #-}
module
Lib
where
import
Safe
(
headMay
)
...
...
@@ -8,32 +21,61 @@ import Data.Map (Map)
import
qualified
Data.Map
as
DM
import
Prelude
someFunc
::
IO
()
someFunc
=
putStrLn
"someFunc"
------------------------------------------------------
-- | Majority Judgment suppose a list of choices and a Ballot for each choice.
-- List should be a Set
type
MajorityJudgment
=
[
Ballot
]
-- | Definition of a ballot
data
Ballot
=
Ballot
{
label
::
Text
,
votes
::
[
Vote
]
}
deriving
(
Show
)
data
Vote
=
Poor
|
Fair
|
Good
|
Excellent
deriving
(
Eq
,
Ord
,
Enum
,
Show
,
Bounded
)
}
example
::
MajorityJudgment
example
=
undefined
instance
Show
Ballot
where
show
(
Ballot
l
vs
)
=
show
(
l
,
score
vs
)
-- | Number of vote per Ballot must be equal ?
data
Vote
=
Poor
|
Fair
|
Good
|
Excellent
deriving
(
Eq
,
Ord
,
Enum
,
Bounded
,
Show
)
------------------------------------------------------------------------
-- | Example application
-- https://en.wikipedia.org/wiki/Majority_judgment
ballots
::
MajorityJudgment
ballots
=
[
Ballot
"Memphis"
(
ratedAs
[(
42
,
Excellent
),(
26
,
Poor
)
,
(
15
,
Poor
)
,
(
17
,
Poor
)])
,
Ballot
"Nashville"
(
ratedAs
[(
42
,
Fair
),(
26
,
Excellent
),
(
15
,
Fair
)
,
(
17
,
Fair
)])
,
Ballot
"Chattanooga"
(
ratedAs
[(
42
,
Poor
),(
26
,
Fair
)
,
(
15
,
Excellent
),
(
17
,
Good
)])
,
Ballot
"Knoxville"
(
ratedAs
[(
42
,
Poor
),(
26
,
Fair
)
,
(
15
,
Good
)
,
(
17
,
Excellent
)])
]
-- | Ballots2 test
-- If voters were more strategic, those from Knoxville and Chattanooga
-- might rate Nashville as "Poor" and Chattanooga as "Excellent", in
-- an attempt to make their preferred candidate Chattanooga win. Also,
-- Nashville voters might rate Knoxville as "poor" to distinguish it from
-- Chattanooga. In spite of these attempts at strategy, the winner would
-- still be Nashville
ballots2
::
MajorityJudgment
ballots2
=
[
Ballot
"Memphis"
(
ratedAs
[(
42
,
Excellent
),(
26
,
Poor
)
,
(
15
,
Poor
)
,
(
17
,
Poor
)])
,
Ballot
"Nashville"
(
ratedAs
[(
42
,
Fair
),(
26
,
Excellent
),
(
15
,
Poor
)
,
(
17
,
Poor
)])
,
Ballot
"Chattanooga"
(
ratedAs
[(
42
,
Poor
),(
26
,
Poor
)
,
(
15
,
Excellent
),
(
17
,
Good
)])
,
Ballot
"Knoxville"
(
ratedAs
[(
42
,
Poor
),(
26
,
Poor
)
,
(
15
,
Excellent
),
(
17
,
Excellent
)])
]
ratedAs
=
concat
.
map
(
\
(
n
,
v
)
->
(
take
n
.
repeat
)
v
)
------------------------------------------------------------------------
-- | Asserts is the Election with Majority Judgment is Fair
-- e.g. methodology of vote is respected to collect the ballots
-- Number of vote per Ballot must be equal
-- add an axiom: must not be Poor at least by one voter ?
-- TODO
isFair
::
MajorityJudgment
->
Bool
isFair
=
undefined
-- all . map (length . votes)
-- | TODO: sortBy and intersect according to Result
-- | Select the Winner
-- TODO: sortBy and intersect according to Result
-- sort then take While equality
winnerIs
::
MajorityJudgment
->
Maybe
Ballot
winnerIs
=
headMay
.
reverse
.
sort
...
...
@@ -43,12 +85,39 @@ instance Eq Ballot where
instance
Ord
Ballot
where
(
compare
)
(
Ballot
_
v1
)
(
Ballot
_
v2
)
=
case
(
==
)
(
score
v1
)
(
score
v2
)
of
False
->
compare
(
score
v1
)
(
score
v2
)
True
->
compare
(
score
$
(
\\
)
v1
(
intersect
v1
v2
))
(
score
$
(
\\
)
v2
(
intersect
v1
v2
))
True
->
compare
(
score
v1'
)
(
score
v2'
)
where
(
v1'
,
v2'
)
=
diff
(
v1
,
v2
)
score
::
[
Vote
]
->
Maybe
Rational
score
=
median
.
map
voteToRational
------------------------------------------------------------------------
diff
::
Ord
a
=>
([
a
],[
a
])
->
([
a
],[
a
])
diff
(
m1
,
m2
)
=
(
fromMap
m1'
,
fromMap
m2'
)
where
(
m1'
,
m2'
)
=
diffMap
(
toMap
m1
,
toMap
m2
)
diffMap
::
Ord
a
=>
(
Map
a
Int
,
Map
a
Int
)
->
(
Map
a
Int
,
Map
a
Int
)
diffMap
(
m1
,
m2
)
=
(
m1'
,
m2'
)
where
m1'
=
DM
.
unionWith
outer
m1
m13
m2'
=
DM
.
unionWith
outer
m2
m23
m13
=
DM
.
intersectionWith
(
-
)
m1
m2
m23
=
DM
.
intersectionWith
(
-
)
m2
m1
outer
a
b
=
if
b
>
0
then
b
else
0
toMap
::
Ord
a
=>
[
a
]
->
Map
a
Int
toMap
=
foldl'
(
\
m
a
->
DM
.
insertWith
(
+
)
a
1
m
)
DM
.
empty
fromMap
::
Map
a
Int
->
[
a
]
fromMap
=
concat
.
map
(
\
(
k
,
n
)
->
(
take
n
.
repeat
)
k
)
.
DM
.
toList
------------------------------------------------------------------------
-- Make instance ScoreVote
voteToRational
::
(
Ord
k
,
Bounded
k
,
Enum
k
)
=>
k
->
Rational
voteToRational
v
=
fromJust
$
DM
.
lookup
v
$
DM
.
fromList
$
zip
vs
[
minimum
+
1
..
minimum
+
(
toRational
.
length
)
vs
]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment