This page was automatically generated by NetLogo 4.1. Questions, problems? Contact feedback@ccl.northwestern.edu.

The applet requires Java 5 or higher. Java must be enabled in your browser settings. Mac users must have Mac OS X 10.4 or higher. Windows and Linux users may obtain the latest Java from Sun's Java site.


In order for this to work, this file, your model file (dct-s.nlogo), and the file NetLogoLite.jar must all be in the same directory. (You can copy NetLogoLite.jar from the directory where you installed NetLogo.)

On some systems, you can test the applet locally on your computer before uploading it to a web server. It doesn't work on all systems, though, so if it doesn't work from your hard drive, please try uploading it to a web server.

You don't need to include everything in this file in your page. If you want, you can just take the HTML code beginning with <applet> and ending with </applet>, and paste it into any HTML file you want. It's even OK to put multiple <applet> tags on a single page.

If NetLogoLite.jar and your model are in different directories, you must modify the archive= and value= lines in the HTML code to point to their actual locations. (For example, if you have multiple applets in different directories on the same web server, you may want to put a single copy of NetLogoLite.jar in one central place and change the archive= lines of all the HTML files to point to that one central copy. This will save disk space for you and download time for your users.)

powered by NetLogo

view/download model file: dct-s.nlogo

WHAT IS IT?

This model tries to explore whether there would be a tax competition among countries (counties) if people could move with no restriction other than a cost of emigration and if there is a democratic choice of redistribution in each country.

At a first glance it may seem obvious that there must be a tax competition among such countries as long as the cost of emigration is low. The reasoning might be like this: if there is more redistribution in one country then in the other one, its more productive inhabitants (who pay more taxes than receive transfers) would leave the country. The least productive inhabitants of other countries would come to enjoy this country's generous transfers. This should force the country to lower both its taxes and its transfers, i.e. to lower its redistribution.

However, this reasoning is false for a simple reason: it assumes the country is an entity that reacts to the outflow of the net payers and inflow of the net receivers in such a way as to keep the first and discourage the later by a change of the tax/transfers system. But this is not true if the level of redistribution is decided democratically and if the voters are only boundedly rational.

In such a case, if an inhabitant emigrates from one country to another one, it makes two effects (both in his former and his new country): 1. few taxes are paid and few transfers demanded in his former countery, and more in his new country and 2. it changes the number of voters in both countries---and also the structure of their electorates.

Let us suppose that one inhabitant in one country believes she could be better off in another country (e.g. because she is a net payer and the tax rate is lower in the other country). If she emmigrates there, the tax revenue in her former country decreases, and the transferes must decrease there as well. However, this need not to force the other inhabitants to decrease the tax rate. Quite contrary, they may even raise the taxes because one person opposing the tax increase was eliminated. If this happens, other inhabitants of the country may emigrate, and the process goes on---possibly forever.


HOW IT WORKS

This section could explain what rules the agents use to create the overall behavior of the model.


HOW TO USE IT

The "Setup" button sets the stage up. Several parameters affect the model initialization. The "#-of-agents" says how many agents will be created. The "default-lazyness" says how much the agents dislike the labor; the higher number, the more they prefer leisure. The "consumption-cost-of-emigration" sets a treshold that must be climbed for the agent to emigrate (this is substracted from his consumption).

The "number-of-initial-tax-haggling-rounds" says how many rounds of haggling about taxes will be used in each country in the set-up process. The more, the more is likely that there will be the tax rate preferred by the median voter. The "number-of-tax-haggling-rounds" means the same for each tick.

The "Go" button starts the simulation. You can visualize several things (see the radio-button).


THINGS TO NOTICE

This section could give some ideas of things for the user to notice while running the model.


THINGS TO TRY

Try to move the "comsumption-cost-of-move" and observe the behavior of the model. Notice that there are faze transitions.


EXTENDING THE MODEL

There are some ways in which I plan to extend the model but I don't want to discuss it here. :-)


NETLOGO FEATURES

The model involves no special NetLogo feature.


RELATED MODELS

I'm not aware of any other similar model but I have to admit that I've skipped the literature review. In a sense, the model is similar to Schelling's famous Segregation model (available in the NetLogo Models Library). In both his and my models a move of one and only discontent person can create a long serie of further moves of other persons. However, if the "consumption-cost-of-move" is small enough, this model need not have a steady state.


CREDITS AND REFERENCES

This section could contain a reference to the model's URL on the web if it has one, as well as any other necessary credits or references.


PROCEDURES

to startup
  setup
end

to setup
  ;movie-start "out.mov"
  let tmpcolor 0
  clear-all
  create-turtles #-of-agents [
    set shape "circle"
    set size 0.02
    setxy random-xcor random-ycor
    setxy ( [ pxcor ] of patch-here + random-float 0.45 - random-float 0.45 ) 
      ( [ pycor ] of patch-here + random-float 0.45 - random-float 0.45 )
    set productivity ( ( 1 + random 100 ) / 100 )
    set laziness default-laziness
  ]
  foreach sort patches [
    ask ? [
      set pcolor ( tmpcolor * 10) + 9
      set tmpcolor tmpcolor + 2
      if-else initial-tax-rate-random? 
        [ set current-tax-rate random 101 ]
        [ set current-tax-rate initial-tax-rate ]
      make-tax-proposal 0
      calculate-tax-proposal
      pass-tax-proposal 
      repeat no-of-initial-tax-haggling-rounds [
        make-tax-proposal max-tax-rate-change
        calculate-tax-proposal
        if ( how-many-benefit? > majority-of-inhabitants? ) [ pass-tax-proposal ]
      ]
    ]
  ]
  ask turtles [
    visualize
  ]
end

to setup-button
  if ( how-to-setup = "user's" ) [
    let my-seed read-from-string user-input "Enter a random seed (an integer):"
;    output-print word "User-entered seed: " my-seed  ;; print it out
    random-seed my-seed             ;; use the new seed
  ]
  setup
end

to go
  ;; change tax system
  repeat no-of-tax-haggling-rounds [
    ask patches [
      make-tax-proposal max-tax-rate-change
      calculate-tax-proposal
;      show ( sentence self proposed-tax-rate proposed-transfers how-many-benefit? majority-of-inhabitants? ) ;; here
      if ( how-many-benefit? > majority-of-inhabitants? ) [ pass-tax-proposal ]
    ]
  ]
  ;; move abroad
  ask turtles [ move ]
  ask patches [ update-tax-system ]
  ;; plotting etc.
  ask turtles [ visualize ]
  tick
  do-plotting
  ;movie-grab-view
end



;; AGENTS
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

turtles-own [ productivity laziness ]

to-report how-much-to-work? [ tax-rate transfer ]
  let t tax-rate let t1 ( 1 - ( t / 100 ) )
  let a productivity
  let f laziness let f2 (f ^ 2 )
  let v transfer
  let l ( t1 * a / ( f2 + t1 * a ) ) - ( f2 / ( t1 * a * ( f2 + t1 * a ) ) ) * v
  if ( l < 0 ) [ set l 0 ]
  if ( l > 1 ) [ set l 1 ]
  report l
end

to-report how-much-is-working?
  report how-much-to-work? [ current-tax-rate ] of patch-here [ current-transfers ] of patch-here
end

to-report how-much-to-produce? [ tax-rate transfers ]
  report productivity * how-much-to-work? tax-rate transfers
end

to-report how-much-is-producing?
  report how-much-to-produce?  [ current-tax-rate ] of patch-here [ current-transfers ] of patch-here
end

to-report how-much-taxes-to-pay? [ tax-rate transfers ]
  report ( tax-rate / 100 ) * how-much-to-produce? tax-rate transfers
end

to-report how-much-taxes-is-paying?
  report how-much-taxes-to-pay? [ current-tax-rate ] of patch-here [current-transfers ] of patch-here
end

to-report how-much-to-consume? [ tax-rate transfers ]
  report transfers + ( 1 - ( tax-rate / 100 ) ) * how-much-to-produce? tax-rate transfers
end

to-report how-much-is-consuming?
  report how-much-to-consume? [ current-tax-rate ] of patch-here [ current-transfers ] of patch-here
end

to-report how-much-utility? [ tax-rate transfers ]
  let c how-much-to-consume? tax-rate transfers
  let h 1 - how-much-to-work? tax-rate transfers
  report ( sqrt c ) + laziness * (sqrt h )
end

to visualize
  if ( visualize? = "none" ) [ set color red ]
  if ( visualize? = "productivity" ) [ set color scale-color blue productivity 0 1 ]
  if ( visualize? = "production" ) [ set color scale-color green how-much-is-producing? 0 0.3 ]
  if ( visualize? = "consumption" ) [ set color scale-color green how-much-is-consuming? 0 0.3 ]
end

to move
  if ( probability-of-considering-move > random 100 ) [
    let p productivity
    let l laziness
    let target max-one-of patches [ how-much-potential-utility-from-patch? p l consumption-cost-of-move ]
    let utility-here [ how-much-potential-utility-from-patch? p l 0 ] of patch-here
    let utility-there [how-much-potential-utility-from-patch? p l consumption-cost-of-move ] of target
    if ( ( target != patch-here ) and ( utility-there > utility-here ) ) [
      setxy ( [ pxcor ] of target + random-float 0.45 - random-float 0.45 ) 
        ( [ pycor ] of target + random-float 0.45 - random-float 0.45 )
    ]
  ]
end





;; PATCHES
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

patches-own [ current-tax-rate current-transfers proposed-tax-rate proposed-transfers ]

to make-tax-proposal [ proposed-max-tax-rate-change ]
  set proposed-tax-rate current-tax-rate - 
    proposed-max-tax-rate-change + random ( ( 2 * proposed-max-tax-rate-change ) + 1 )
  if ( proposed-tax-rate < 0 ) [ set proposed-tax-rate 0 ]
  if ( proposed-tax-rate > 100 ) [ set proposed-tax-rate 100 ]
;  show ( sentence self proposed-tax-rate ) ;; here
  set proposed-transfers 0
end

to calculate-tax-proposal
  let number-of-inhabitants count turtles-here
  let old-transfers 0
  let tmp 0
  loop [
    set tmp old-transfers
    set old-transfers proposed-transfers
    set proposed-transfers ( proposed-transfers + tmp ) / 2
    ifelse ( number-of-inhabitants = 0 ) 
    [ 
      set proposed-transfers 0 
    ] 
    [ 
      set proposed-transfers proposed-tax-revenue? / number-of-inhabitants 
    ]
    if ( ( proposed-transfers - old-transfers ) = 0 ) [ stop]
    if ( abs ( proposed-transfers - old-transfers ) / ( max list proposed-transfers old-transfers ) < 0.0001 )
      [ stop ]
  ]
end

to pass-tax-proposal
  set current-tax-rate proposed-tax-rate
  set current-transfers proposed-transfers
end

to update-tax-system
  if-else ( ( how-many-inhabitants? = 0 ) and reset-tax-rate-in-empty-county-to-zero? )
    [ set current-tax-rate 0
      set current-transfers  0
    ]
    [ 
      make-tax-proposal 0
      calculate-tax-proposal
      pass-tax-proposal
    ]
end

to-report how-many-benefit?
  report count turtles-here with [ 
    ( how-much-utility? current-tax-rate current-transfers ) < ;; <= this is important decision -- what is more realistic?
    ( how-much-utility? proposed-tax-rate proposed-transfers )
  ]
end

to-report how-many-inhabitants?
  report count turtles-here
end

to-report majority-of-inhabitants?
  report how-many-inhabitants? / 2
end

to-report proposed-tax-revenue?
  report sum [ how-much-taxes-to-pay? proposed-tax-rate proposed-transfers ] of turtles-here
end

to-report current-tax-revenue?
  report sum [ how-much-taxes-to-pay? current-tax-rate current-transfers ] of turtles-here
end

to-report how-much-potential-utility-from-patch? [ agents-productivity agents-laziness consumption-cost ]
  let t current-tax-rate let t1 ( 1 - ( t / 100 ) )
  let a agents-productivity
  let f agents-laziness let f2 (f ^ 2 )
  let v current-transfers
  let l ( t1 * a / ( f2 + t1 * a ) ) - ( f2 / ( t1 * a * ( f2 + t1 * a ) ) ) * v
  if ( l < 0 ) [ set l 0 ]
  if ( l > 1 ) [ set l 1 ]
  let prod a * l ;; production
  let c current-transfers + ( 1 - ( t / 100 ) ) * prod - consumption-cost ;; consumption
  if ( c < 0 ) [ set c 0 ]
  let h 1 - l
  report ( sqrt c ) + f * (sqrt h )
end

to-report plot-mean-productivity-of-patch [ pxc pyc ]
  if-else ( [ how-many-inhabitants? ] of patch pxc pyc > 0 )
    [ report ( ( mean [ productivity ] of turtles-on patch pxc pyc ) * 1000 ) ]
    [ report 0 ]
end

to-report plot-mean-consumption-of-patch [ pxc pyc ]
  if-else ( [ how-many-inhabitants? ] of patch pxc pyc > 0 )
    [ report ( ( mean [ how-much-to-consume? current-tax-rate current-transfers ] of turtles-on patch pxc pyc ) * 1000 ) ]
    [ report 0 ]
end

to-report current-budget-deficit?
  report current-tax-revenue? - current-transfers * how-many-inhabitants?
end





; OBSERVER
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to-report number-of-net-payers-on? [ loc ]
  report count ( turtles-on loc ) with [ how-much-taxes-is-paying? > ( [ current-transfers ] of loc ) ]
end

to-report number-of-net-gainers-on? [ loc ]
  report count ( turtles-on loc ) with [ how-much-taxes-is-paying? < ( [ current-transfers ] of loc ) ]
end

to-report mean-production-on? [ loc ]
  if-else ( ( count turtles-on loc ) > 0 ) [
    report mean [ how-much-is-producing? ] of turtles-on loc ] [
    report "NaN" ]
end

to-report mean-possible-production-on? [ loc ]
  if-else ( ( count turtles-on loc ) > 0 ) [
    report mean [ how-much-to-produce? 0 0 ] of turtles-on loc ] [
    report "NaN" ]
end

to-report mean-product-lost-on? [ loc ]

  if-else ( ( count turtles-on loc ) > 0 ) [
    report mean-possible-production-on? loc - mean-production-on? loc ] [
    report "NaN" ]
end
to-report mean-consumption-on? [ loc ]
  if-else ( ( count turtles-on loc ) > 0 ) [
    report mean [ how-much-is-consuming?] of turtles-on loc ] [
    report "NaN" ]
end

to-report mean-productivity-on? [ loc ]
  if-else ( ( count turtles-on loc ) > 0 ) [
  report mean [ productivity ] of turtles-on loc ] [
  report "NaN" ]
end

to-report median-productivity-on? [ loc ]
  if-else ( ( count turtles-on loc ) > 0 ) [
  report median [ productivity ] of turtles-on loc ] [
  report "NaN" ]
end

to-report min-productivity-on? [ loc ]
  if-else ( ( count turtles-on loc ) > 0 ) [
  report min [ productivity ] of turtles-on loc ] [
  report "NaN" ]
end

to-report max-productivity-on? [ loc ]
  if-else ( ( count turtles-on loc ) > 0 ) [
  report max [ productivity ] of turtles-on loc ] [
  report "NaN" ]
end

to-report std-productivity-on? [ loc ]
  if-else ( ( count turtles-on loc ) > 1 ) [
  report standard-deviation [ productivity ] of turtles-on loc ] [
  report "NaN" ]
end





;; PLOTTING
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to do-plotting
  ;; Taxes and Transferes
  set-current-plot "Taxes and Transfers"
  set-current-plot-pen "Tax Rate 0 0"
  plot [ current-tax-rate ] of patch 0 0
  set-current-plot-pen "Transfers 0 0"
  plot ( ( [ current-transfers] of patch 0 0 ) * 1000 )
  set-current-plot-pen "Tax Rate 1 0"
  plot [ current-tax-rate ] of patch 1 0
  set-current-plot-pen "Transfers 1 0"
  plot ( ( [ current-transfers] of patch 1 0 ) * 1000 )
  ;;
  ;; Productivity and Consumption
  set-current-plot "Productivity and Consumption"
  set-current-plot-pen "Productivity 0 0"
  plot plot-mean-productivity-of-patch 0 0
  set-current-plot-pen "Consumption 0 0"
  plot plot-mean-consumption-of-patch 0 0
  set-current-plot-pen "Productivity 1 0"
  plot plot-mean-productivity-of-patch 1 0
  set-current-plot-pen "Consumption 1 0"
  plot plot-mean-consumption-of-patch 1 0
  ;;
  ;; Inhabitants
  set-current-plot "Inhabitants"
  set-current-plot-pen "Inhabitants 0 0"
  plot [ how-many-inhabitants? ] of patch 0 0
  set-current-plot-pen "Net-gainers 0 0"
  plot count ( turtles-on patch 0 0 ) with 
    [ ( how-much-taxes-to-pay? [ current-tax-rate ] of patch 0 0 [ current-transfers ] of patch 0 0 ) 
      < ( [ current-transfers ] of patch 0 0 ) ]
  set-current-plot-pen "Net-payers 0 0"
  plot count ( turtles-on patch 0 0 ) with 
    [ ( how-much-taxes-to-pay? [ current-tax-rate ] of patch 0 0 [ current-transfers ] of patch 0 0 ) 
      > ( [ current-transfers ] of patch 0 0 ) ]
  set-current-plot-pen "Inhabitants 1 0"
  plot [ how-many-inhabitants? ] of patch 1 0
  set-current-plot-pen "Net-gainers 1 0"
  plot count ( turtles-on patch 1 0 ) with 
    [ ( how-much-taxes-to-pay? [ current-tax-rate ] of patch 1 0 [ current-transfers ] of patch 1 0 ) 
      < ( [ current-transfers ] of patch 1 0 ) ]
  set-current-plot-pen "Net-payers 1 0"
  plot count ( turtles-on patch 1 0 ) with 
    [ ( how-much-taxes-to-pay? [ current-tax-rate ] of patch 1 0 [ current-transfers ] of patch 1 0 ) 
      > ( [ current-transfers ] of patch 1 0 ) ]
end

;; taken from Models Library: Sample Models: Social Science: Wealth Distribution
to-report gini-on? [ loc ]
  let #-of-agents-here count turtles-on loc
  if-else ( #-of-agents-here = 0 ) [
    report "NaN" ] [
    let sorted-wealths sort [ how-much-is-consuming? ] of turtles-on loc
    let total-wealth sum sorted-wealths
    let wealth-sum-so-far 0
    let index 0
    let gini-index-reserve 0
    repeat #-of-agents-here [
      set wealth-sum-so-far ( wealth-sum-so-far + item index sorted-wealths )
      set index (index + 1)
      set gini-index-reserve gini-index-reserve + ( index / #-of-agents-here ) - ( wealth-sum-so-far / total-wealth )
    ]
    report ( gini-index-reserve / #-of-agents-here ) / 0.5 ]
end

to-report potential-gini-on? [ loc ]
  let #-of-agents-here count turtles-on loc
  if-else ( #-of-agents-here = 0 ) [
    report "NaN" ] [
    let sorted-wealths sort [ how-much-to-produce? 0 0 ] of turtles-on loc
    let total-wealth sum sorted-wealths
    let wealth-sum-so-far 0
    let index 0
    let gini-index-reserve 0
    repeat #-of-agents-here [
      set wealth-sum-so-far ( wealth-sum-so-far + item index sorted-wealths )
      set index (index + 1)
      set gini-index-reserve gini-index-reserve + ( index / #-of-agents-here ) - ( wealth-sum-so-far / total-wealth )
    ]
    report ( gini-index-reserve / #-of-agents-here ) / 0.5 ]
end

;to update-lorenz-and-gini-plots
;  set-current-plot "Lorenz Curve"
;  clear-plot
;
;  ;; draw a straight line from lower left to upper right
;  set-current-plot-pen "equal"
;  plot 0
;  plot 100
;
;  set-current-plot-pen "lorenz"
;  set-plot-pen-interval 100 / #-of-agents
;  plot 0
;
;  let sorted-wealths sort [ how-much-is-consuming? ] of turtles
;  let total-wealth sum sorted-wealths
;  let wealth-sum-so-far 0
;  let index 0
;  let gini-index-reserve 0
;
;  ;; now actually plot the Lorenz curve -- along the way, we also
;  ;; calculate the Gini index.
;  ;; (see the Information tab for a description of the curve and measure)
;  repeat #-of-agents [
;    set wealth-sum-so-far (wealth-sum-so-far + item index sorted-wealths)
;    plot (wealth-sum-so-far / total-wealth) * 100
;    set index (index + 1)
;    set gini-index-reserve
;      gini-index-reserve +
;      (index / #-of-agents) -
;      (wealth-sum-so-far / total-wealth)
;  ]
;
;  ;; plot Gini Index
;  set-current-plot "Gini-Index v. Time"
;  plot (gini-index-reserve / #-of-agents) / 0.5
;end