Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 8af1c246 authored by Denis Merigoux's avatar Denis Merigoux
Browse files

Cleaned 2019 and 2020 IR code

parent 99285dd4
Branches
No related tags found
No related merge requests found
......@@ -25,87 +25,87 @@ from typing import Optional, Union, Any, List
from solveur import *
class TrancheIR:
class TrancheIR2019:
def __init__(self, min: Montant, max: Optional[Montant], t: Taux):
self.min = min
self.max = max
self.taux = t
@staticmethod
def tranche1(s: Solver) -> 'TrancheIR':
return TrancheIR(
def tranche1(s: Solver) -> 'TrancheIR2019':
return TrancheIR2019(
Montant.euros(0, s),
Montant.euros(9965, s),
Taux.pourcent(0)
)
@staticmethod
def tranche1_2020(s: Solver) -> 'TrancheIR':
return TrancheIR(
def tranche1_2020(s: Solver) -> 'TrancheIR2019':
return TrancheIR2019(
Montant.euros(0, s),
Montant.euros(10064, s),
Taux.pourcent(0)
)
@staticmethod
def tranche2(s: Solver) -> 'TrancheIR':
return TrancheIR(
def tranche2(s: Solver) -> 'TrancheIR2019':
return TrancheIR2019(
Montant.euros(9965, s),
Montant.euros(27520, s),
Taux.pourcent(14)
)
@staticmethod
def tranche2_2020(s: Solver) -> 'TrancheIR':
return TrancheIR(
def tranche2_2020(s: Solver) -> 'TrancheIR2019':
return TrancheIR2019(
Montant.euros(10065, s),
Montant.euros(25659, s),
Taux.pourcent(11)
)
@staticmethod
def tranche3(s: Solver) -> 'TrancheIR':
return TrancheIR(
def tranche3(s: Solver) -> 'TrancheIR2019':
return TrancheIR2019(
Montant.euros(27520, s),
Montant.euros(73780, s),
Taux.pourcent(30)
)
@staticmethod
def tranche3_2020(s: Solver) -> 'TrancheIR':
return TrancheIR(
def tranche3_2020(s: Solver) -> 'TrancheIR2019':
return TrancheIR2019(
Montant.euros(25660, s),
Montant.euros(73369, s),
Taux.pourcent(30)
)
@staticmethod
def tranche4(s: Solver) -> 'TrancheIR':
return TrancheIR(
def tranche4(s: Solver) -> 'TrancheIR2019':
return TrancheIR2019(
Montant.euros(73780, s),
Montant.euros(156245, s),
Taux.pourcent(41)
)
@staticmethod
def tranche4_2020(s: Solver) -> 'TrancheIR':
return TrancheIR(
def tranche4_2020(s: Solver) -> 'TrancheIR2019':
return TrancheIR2019(
Montant.euros(73370, s),
Montant.euros(157806, s),
Taux.pourcent(41)
)
@staticmethod
def tranche5(s: Solver) -> 'TrancheIR':
return TrancheIR(
def tranche5(s: Solver) -> 'TrancheIR2019':
return TrancheIR2019(
Montant.euros(156245, s),
None,
Taux.pourcent(45)
)
@staticmethod
def tranche5_2020(s: Solver) -> 'TrancheIR':
return TrancheIR(
def tranche5_2020(s: Solver) -> 'TrancheIR2019':
return TrancheIR2019(
Montant.euros(157807, s),
None,
Taux.pourcent(45)
......@@ -124,7 +124,7 @@ class TrancheIR:
return self.revenu_tranche(r, s) % self.taux
class QuotientFamilial:
class QuotientFamilial2019:
counter: int = 0
def __init__(self, parts: Union[int, BitVecVal, BitVec], plafond_q_f: Montant, plafond_num_rscr: Montant, plafond_rscr: Montant):
......@@ -133,8 +133,8 @@ class QuotientFamilial:
self.plafond_num_rscr = plafond_num_rscr
self.plafond_rscr = plafond_rscr
def __add__(self, rhs: 'QuotientFamilial') -> 'QuotientFamilial':
return QuotientFamilial(
def __add__(self, rhs: 'QuotientFamilial2019') -> 'QuotientFamilial2019':
return QuotientFamilial2019(
self.demi_parts + rhs.demi_parts,
self.plafond_q_f + rhs.plafond_q_f,
self.plafond_num_rscr + rhs.plafond_num_rscr,
......@@ -158,8 +158,8 @@ class QuotientFamilial:
)
@staticmethod
def variable(name: str, s: Solver) -> 'QuotientFamilial':
q_f = QuotientFamilial(
def variable(name: str, s: Solver) -> 'QuotientFamilial2019':
q_f = QuotientFamilial2019(
BitVec(name + "_demi_parts", repr_bits),
Montant.anonyme(s, name + "_plafond_q_f"),
Montant.anonyme(s, name + "_plafond_num_rscr"),
......@@ -170,17 +170,17 @@ class QuotientFamilial:
return q_f
@staticmethod
def anonyme(s: Solver) -> 'QuotientFamilial':
out = QuotientFamilial.variable("qf{}".format(QuotientFamilial.counter), s)
QuotientFamilial.counter += 1
def anonyme(s: Solver) -> 'QuotientFamilial2019':
out = QuotientFamilial2019.variable("qf{}".format(QuotientFamilial2019.counter), s)
QuotientFamilial2019.counter += 1
return out
@staticmethod
def diviser(r: Montant, q_f: 'QuotientFamilial', s: Solver) -> Montant:
def diviser(r: Montant, q_f: 'QuotientFamilial2019', s: Solver) -> Montant:
return (r // q_f.demi_parts) * 2
@staticmethod
def multiplier(r: Montant, qf: 'QuotientFamilial') -> Montant:
def multiplier(r: Montant, qf: 'QuotientFamilial2019') -> Montant:
return (r * qf.demi_parts) // 2
@staticmethod
......@@ -224,252 +224,248 @@ class QuotientFamilial:
return Montant.euros(3737, s)
@staticmethod
def celibataire(f: FoyerFiscal, s: Solver) -> 'QuotientFamilial':
qf = QuotientFamilial.anonyme(s)
def celibataire(f: FoyerFiscal, s: Solver) -> 'QuotientFamilial2019':
qf = QuotientFamilial2019.anonyme(s)
enfants_minus_2 = Montant.bitvec_sat_sub(f.nb_personnes_a_charge, 2, s)
# Veuf
qf_target = QuotientFamilial(
qf_target = QuotientFamilial2019(
2,
Montant.euros(0, s),
QuotientFamilial.plafond_num_rscr_celibataire(s),
QuotientFamilial.plafond_rscr_celibataire(s)
QuotientFamilial2019.plafond_num_rscr_celibataire(s),
QuotientFamilial2019.plafond_rscr_celibataire(s)
)
s.add(Implies(And(f.veuf, f.nb_personnes_a_charge == 0), qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
3,
QuotientFamilial.plafond_enfant_a_charge_veuf(s),
QuotientFamilial.plafond_num_rscr_demi_part(s) * 3,
QuotientFamilial.plafond_rscr_demi_part(s) * 3,
QuotientFamilial2019.plafond_enfant_a_charge_veuf(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s) * 3,
QuotientFamilial2019.plafond_rscr_demi_part(s) * 3,
)
s.add(Implies(And(f.veuf, f.nb_personnes_a_charge == 1), qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
1,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s),
QuotientFamilial.plafond_rscr_demi_part(s)
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s),
QuotientFamilial2019.plafond_rscr_demi_part(s)
)
s.add(Implies(And(f.veuf, f.nb_personnes_a_charge == 2), qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
2 * enfants_minus_2,
QuotientFamilial.plafond_enfant_a_charge(s) * enfants_minus_2,
QuotientFamilial.plafond_num_rscr_demi_part(s) * 2 * enfants_minus_2,
QuotientFamilial.plafond_rscr_demi_part(s) * 2 * enfants_minus_2,
QuotientFamilial2019.plafond_enfant_a_charge(s) * enfants_minus_2,
QuotientFamilial2019.plafond_num_rscr_demi_part(s) * 2 * enfants_minus_2,
QuotientFamilial2019.plafond_rscr_demi_part(s) * 2 * enfants_minus_2,
)
s.add(Implies(And(f.veuf, f.nb_personnes_a_charge >= 3), qf == qf_target))
# Parent isolé
qf_target = QuotientFamilial(
qf_target = QuotientFamilial2019(
2,
Montant.euros(0, s),
QuotientFamilial.plafond_num_rscr_celibataire(s),
QuotientFamilial.plafond_rscr_celibataire(s)
QuotientFamilial2019.plafond_num_rscr_celibataire(s),
QuotientFamilial2019.plafond_rscr_celibataire(s)
)
s.add(Implies(And(f.parent_isole, f.nb_personnes_a_charge == 0), qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
2,
QuotientFamilial.plafond_enfant_a_charge_parent_isole(s),
QuotientFamilial.plafond_num_rscr_demi_part(s) * 2,
QuotientFamilial.plafond_rscr_demi_part(s) * 2
QuotientFamilial2019.plafond_enfant_a_charge_parent_isole(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s) * 2,
QuotientFamilial2019.plafond_rscr_demi_part(s) * 2
)
s.add(Implies(And(f.parent_isole, f.nb_personnes_a_charge == 1), qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
1,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s),
QuotientFamilial.plafond_rscr_demi_part(s)
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s),
QuotientFamilial2019.plafond_rscr_demi_part(s)
)
s.add(Implies(And(f.parent_isole, f.nb_personnes_a_charge == 2), qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
2 * enfants_minus_2,
QuotientFamilial.plafond_enfant_a_charge(s) * enfants_minus_2,
QuotientFamilial.plafond_num_rscr_demi_part(s) * 2 * enfants_minus_2,
QuotientFamilial.plafond_rscr_demi_part(s) * 2 * enfants_minus_2
QuotientFamilial2019.plafond_enfant_a_charge(s) * enfants_minus_2,
QuotientFamilial2019.plafond_num_rscr_demi_part(s) * 2 * enfants_minus_2,
QuotientFamilial2019.plafond_rscr_demi_part(s) * 2 * enfants_minus_2
)
s.add(Implies(And(f.parent_isole, f.nb_personnes_a_charge >= 3), qf == qf_target))
# Normal
parent_normal = Not(Or(f.parent_isole, f.veuf))
qf_target = QuotientFamilial(
qf_target = QuotientFamilial2019(
2,
Montant.euros(0, s),
QuotientFamilial.plafond_num_rscr_celibataire(s),
QuotientFamilial.plafond_rscr_celibataire(s)
QuotientFamilial2019.plafond_num_rscr_celibataire(s),
QuotientFamilial2019.plafond_rscr_celibataire(s)
)
s.add(Implies(And(parent_normal, f.nb_personnes_a_charge == 0), qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
1,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s),
QuotientFamilial.plafond_rscr_demi_part(s)
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s),
QuotientFamilial2019.plafond_rscr_demi_part(s)
)
s.add(Implies(And(parent_normal, f.nb_personnes_a_charge == 1), qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
1,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s),
QuotientFamilial.plafond_rscr_demi_part(s)
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s),
QuotientFamilial2019.plafond_rscr_demi_part(s)
)
s.add(Implies(And(parent_normal, f.nb_personnes_a_charge == 2), qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
2 * enfants_minus_2,
QuotientFamilial.plafond_enfant_a_charge(s) * enfants_minus_2,
QuotientFamilial.plafond_num_rscr_demi_part(s) * 2 * enfants_minus_2,
QuotientFamilial.plafond_rscr_demi_part(s) * 2 * enfants_minus_2
QuotientFamilial2019.plafond_enfant_a_charge(s) * enfants_minus_2,
QuotientFamilial2019.plafond_num_rscr_demi_part(s) * 2 * enfants_minus_2,
QuotientFamilial2019.plafond_rscr_demi_part(s) * 2 * enfants_minus_2
)
s.add(Implies(And(parent_normal, f.nb_personnes_a_charge >= 3), qf == qf_target))
return qf
@staticmethod
def concubinage(f: FoyerFiscal, s: Solver) -> 'QuotientFamilial':
qf = QuotientFamilial.anonyme(s)
def concubinage(f: FoyerFiscal, s: Solver) -> 'QuotientFamilial2019':
qf = QuotientFamilial2019.anonyme(s)
enfants_minus_4 = Montant.bitvec_sat_sub(f.nb_personnes_a_charge, 4, s)
qf_target = QuotientFamilial(
qf_target = QuotientFamilial2019(
2,
Montant.euros(0, s),
QuotientFamilial.plafond_num_rscr_celibataire(s),
QuotientFamilial.plafond_rscr_celibataire(s)
QuotientFamilial2019.plafond_num_rscr_celibataire(s),
QuotientFamilial2019.plafond_rscr_celibataire(s)
)
s.add(Implies(f.nb_personnes_a_charge == 0, qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
1,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s),
QuotientFamilial.plafond_rscr_demi_part(s)
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s),
QuotientFamilial2019.plafond_rscr_demi_part(s)
)
s.add(Implies(f.nb_personnes_a_charge == 1, qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
1,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s),
QuotientFamilial.plafond_rscr_demi_part(s)
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s),
QuotientFamilial2019.plafond_rscr_demi_part(s)
)
s.add(Implies(f.nb_personnes_a_charge == 2, qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
2,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s) * 2,
QuotientFamilial.plafond_rscr_demi_part(s) * 2
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s) * 2,
QuotientFamilial2019.plafond_rscr_demi_part(s) * 2
)
s.add(Implies(f.nb_personnes_a_charge == 3, qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
2,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s) * 2,
QuotientFamilial.plafond_rscr_demi_part(s) * 2
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s) * 2,
QuotientFamilial2019.plafond_rscr_demi_part(s) * 2
)
s.add(Implies(f.nb_personnes_a_charge == 4, qf == qf_target))
qf_target = QuotientFamilial(
qf_target = QuotientFamilial2019(
2 * enfants_minus_4,
QuotientFamilial.plafond_enfant_a_charge(s) * enfants_minus_4,
QuotientFamilial.plafond_num_rscr_demi_part(s) * 2 * enfants_minus_4,
QuotientFamilial.plafond_rscr_demi_part(s) * 2 * enfants_minus_4
QuotientFamilial2019.plafond_enfant_a_charge(s) * enfants_minus_4,
QuotientFamilial2019.plafond_num_rscr_demi_part(s) * 2 * enfants_minus_4,
QuotientFamilial2019.plafond_rscr_demi_part(s) * 2 * enfants_minus_4
)
s.add(Implies(f.nb_personnes_a_charge >= 5, qf == qf_target))
return qf
@staticmethod
def couple(f: FoyerFiscal, s: Solver) -> 'QuotientFamilial':
qf = QuotientFamilial.anonyme(s)
def couple(f: FoyerFiscal, s: Solver) -> 'QuotientFamilial2019':
qf = QuotientFamilial2019.anonyme(s)
enfants_minus_4 = Montant.bitvec_sat_sub(f.nb_personnes_a_charge, 4, s)
qf_target = QuotientFamilial(
qf_target = QuotientFamilial2019(
4,
Montant.euros(0, s),
QuotientFamilial.plafond_num_rscr_couple(s),
QuotientFamilial.plafond_rscr_couple(s)
QuotientFamilial2019.plafond_num_rscr_couple(s),
QuotientFamilial2019.plafond_rscr_couple(s)
)
s.add(Implies(f.nb_personnes_a_charge == 0, qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
1,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s),
QuotientFamilial.plafond_rscr_demi_part(s)
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s),
QuotientFamilial2019.plafond_rscr_demi_part(s)
)
s.add(Implies(f.nb_personnes_a_charge == 1, qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
1,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s),
QuotientFamilial.plafond_rscr_demi_part(s)
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s),
QuotientFamilial2019.plafond_rscr_demi_part(s)
)
s.add(Implies(f.nb_personnes_a_charge == 2, qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
2,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s) * 2,
QuotientFamilial.plafond_rscr_demi_part(s) * 2
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s) * 2,
QuotientFamilial2019.plafond_rscr_demi_part(s) * 2
)
s.add(Implies(f.nb_personnes_a_charge == 3, qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
2,
QuotientFamilial.plafond_enfant_a_charge(s),
QuotientFamilial.plafond_num_rscr_demi_part(s) * 2,
QuotientFamilial.plafond_rscr_demi_part(s) * 2
QuotientFamilial2019.plafond_enfant_a_charge(s),
QuotientFamilial2019.plafond_num_rscr_demi_part(s) * 2,
QuotientFamilial2019.plafond_rscr_demi_part(s) * 2
)
s.add(Implies(f.nb_personnes_a_charge == 4, qf == qf_target))
qf_target += QuotientFamilial(
qf_target += QuotientFamilial2019(
2 * enfants_minus_4,
QuotientFamilial.plafond_enfant_a_charge(s) * enfants_minus_4,
QuotientFamilial.plafond_num_rscr_demi_part(s) * 2 * enfants_minus_4,
QuotientFamilial.plafond_rscr_demi_part(s) * 2 * enfants_minus_4
QuotientFamilial2019.plafond_enfant_a_charge(s) * enfants_minus_4,
QuotientFamilial2019.plafond_num_rscr_demi_part(s) * 2 * enfants_minus_4,
QuotientFamilial2019.plafond_rscr_demi_part(s) * 2 * enfants_minus_4
)
s.add(Implies(f.nb_personnes_a_charge >= 5, qf == qf_target))
return qf
@staticmethod
def nombre(f: FoyerFiscal, s: Solver) -> 'QuotientFamilial':
base = QuotientFamilial.anonyme(s)
def nombre(f: FoyerFiscal, s: Solver) -> 'QuotientFamilial2019':
base = QuotientFamilial2019.anonyme(s)
s.add(Implies(
f.composition == Composition.celibataire(),
base == QuotientFamilial.celibataire(f, s)
base == QuotientFamilial2019.celibataire(f, s)
))
s.add(Implies(
f.composition == Composition.concubinage(),
base == QuotientFamilial.concubinage(f, s)
base == QuotientFamilial2019.concubinage(f, s)
))
s.add(Implies(
f.composition == Composition.couple(),
base == QuotientFamilial.couple(f, s)
base == QuotientFamilial2019.couple(f, s)
))
invalides_a_charge = f.nb_invalides_a_charge(s)
return base + QuotientFamilial(
return base + QuotientFamilial2019(
invalides_a_charge,
QuotientFamilial.plafond_enfant_a_charge_invalide(s) * invalides_a_charge,
QuotientFamilial2019.plafond_enfant_a_charge_invalide(s) * invalides_a_charge,
Montant.euros(0, s),
Montant.euros(0, s)
)
class IR:
class IR2019:
counter: int = 0
def __init__(self, f: FoyerFiscal):
self.foyer = f
self.plafonnement_q_f_actif = Bool("plafonnement_q_f_actif{}".format(IR.counter))
IR.counter += 1
self.decote_actif = Bool("decote_actif{}".format(IR.counter))
IR.counter += 1
self.non_prelemevement_actif = Bool("non_prelemevement_actif{}".format(IR.counter))
IR.counter += 1
self.plafonnement_q_f_actif = Bool("plafonnement_q_f_actif{}".format(IR2019.counter))
IR2019.counter += 1
self.decote_actif = Bool("decote_actif{}".format(IR2019.counter))
IR2019.counter += 1
self.non_prelemevement_actif = Bool("non_prelemevement_actif{}".format(IR2019.counter))
IR2019.counter += 1
self.impot_sans_q_f_: Optional[Montant] = None
self.impot_avec_q_f_: Optional[Montant] = None
self.impot_sans_q_f_2020_: Optional[Montant] = None
self.impot_avec_q_f_2020_: Optional[Montant] = None
self.montant_: Optional[Montant] = None
self.montant_2020_: Optional[Montant] = None
self.calcul_avec_etapes_: Optional[List[Montant]] = None
self.calcul_avec_etapes_2020_: Optional[List[Montant]] = None
@staticmethod
def denominateur_rscr_celibataire(s: Solver) -> Montant:
......@@ -481,46 +477,30 @@ class IR:
@staticmethod
def montant_selon_revenu(r: Montant, s: Solver) -> Montant:
return (TrancheIR.tranche1(s).montant(r, s) +
TrancheIR.tranche2(s).montant(r, s) +
TrancheIR.tranche3(s).montant(r, s) +
TrancheIR.tranche4(s).montant(r, s) +
TrancheIR.tranche5(s).montant(r, s))
@staticmethod
def montant_selon_revenu_2020(r: Montant, s: Solver) -> Montant:
return (TrancheIR.tranche1_2020(s).montant(r, s) +
TrancheIR.tranche2_2020(s).montant(r, s) +
TrancheIR.tranche3_2020(s).montant(r, s) +
TrancheIR.tranche4_2020(s).montant(r, s) +
TrancheIR.tranche5_2020(s).montant(r, s))
return (TrancheIR2019.tranche1(s).montant(r, s) +
TrancheIR2019.tranche2(s).montant(r, s) +
TrancheIR2019.tranche3(s).montant(r, s) +
TrancheIR2019.tranche4(s).montant(r, s) +
TrancheIR2019.tranche5(s).montant(r, s))
@staticmethod
def plafond_decote_celibataire(s: Solver) -> Montant:
return Montant.euros(1594, s)
@staticmethod
def plafond_decote_celibataire_2020(s: Solver) -> Montant:
return Montant.euros(777, s)
@staticmethod
def plafond_decote_couple(s: Solver) -> Montant:
return Montant.euros(2626, s)
@staticmethod
def plafond_decote_couple_2020(s: Solver) -> Montant:
return Montant.euros(1286, s)
def decote(self, ir: Montant, s: Solver) -> Montant:
plafond = Montant.anonyme(s, "plafond_decote")
s.add(Implies(
Or(self.foyer.composition == Composition.celibataire(),
self.foyer.composition == Composition.concubinage()),
plafond == IR.plafond_decote_celibataire(s)
plafond == IR2019.plafond_decote_celibataire(s)
))
s.add(Implies(
self.foyer.composition == Composition.couple(),
plafond == IR.plafond_decote_couple(s)
plafond == IR2019.plafond_decote_couple(s)
))
decote_montant = (plafond % Taux.pourcent(75)).sub(ir % Taux.pourcent(75))
......@@ -533,96 +513,43 @@ class IR:
return decote.round_to_euro()
def decote_2020(self, ir: Montant, s: Solver) -> Montant:
plafond = Montant.anonyme(s, "plafond_decote")
s.add(Implies(
Or(self.foyer.composition == Composition.celibataire(),
self.foyer.composition == Composition.concubinage()),
plafond == IR.plafond_decote_celibataire_2020(s)
))
s.add(Implies(
self.foyer.composition == Composition.couple(),
plafond == IR.plafond_decote_couple_2020(s)
))
decote_montant = plafond.sub(ir % Taux.pourmille(453))
decote = Montant.anonyme(s, "decote")
s.add(Implies(decote_montant < Montant.euros(0, s), decote == Montant.euros(0, s)))
s.add(Implies(decote_montant >= Montant.euros(0, s),
decote == decote_montant
))
return decote.round_to_euro()
def impot_sans_q_f(self, s: Solver) -> Montant:
if self.impot_sans_q_f_ is None:
rfr = self.foyer.revenu_fiscal_reference(s)
sans_q_f = QuotientFamilial(
sans_q_f = QuotientFamilial2019(
2 * self.foyer.nb_personnes(s),
Montant.euros(0, s),
Montant.euros(0, s),
Montant.euros(0, s)
)
rev_sans_q_f = QuotientFamilial.diviser(rfr, sans_q_f, s)
impot_par_part_sans_q_f = IR.montant_selon_revenu(rev_sans_q_f, s)
self.impot_sans_q_f_ = QuotientFamilial.multiplier(impot_par_part_sans_q_f, sans_q_f).round_to_euro()
rev_sans_q_f = QuotientFamilial2019.diviser(rfr, sans_q_f, s)
impot_par_part_sans_q_f = IR2019.montant_selon_revenu(rev_sans_q_f, s)
self.impot_sans_q_f_ = QuotientFamilial2019.multiplier(impot_par_part_sans_q_f, sans_q_f).round_to_euro()
return self.impot_sans_q_f_
def impot_sans_q_f_2020(self, s: Solver) -> Montant:
if self.impot_sans_q_f_2020_ is None:
rfr = self.foyer.revenu_fiscal_reference(s)
sans_q_f = QuotientFamilial(
2 * self.foyer.nb_personnes(s),
Montant.euros(0, s),
Montant.euros(0, s),
Montant.euros(0, s)
)
rev_sans_q_f = QuotientFamilial.diviser(rfr, sans_q_f, s)
impot_par_part_sans_q_f = IR.montant_selon_revenu_2020(rev_sans_q_f, s)
self.impot_sans_q_f_2020_ = QuotientFamilial.multiplier(impot_par_part_sans_q_f, sans_q_f).round_to_euro()
return self.impot_sans_q_f_2020_
def impot_avec_q_f(self, s: Solver) -> Montant:
if self.impot_avec_q_f_ is None:
rfr = self.foyer.revenu_fiscal_reference(s)
q_f = QuotientFamilial.nombre(self.foyer, s)
q_f = QuotientFamilial2019.nombre(self.foyer, s)
rev_q_f = QuotientFamilial.diviser(rfr, q_f, s)
impot_par_part_q_f = IR.montant_selon_revenu(rev_q_f, s)
rev_q_f = QuotientFamilial2019.diviser(rfr, q_f, s)
impot_par_part_q_f = IR2019.montant_selon_revenu(rev_q_f, s)
self.impot_avec_q_f_ = QuotientFamilial.multiplier(impot_par_part_q_f, q_f).round_to_euro()
self.impot_avec_q_f_ = QuotientFamilial2019.multiplier(impot_par_part_q_f, q_f).round_to_euro()
return self.impot_avec_q_f_
def impot_avec_q_f_2020(self, s: Solver) -> Montant:
if self.impot_avec_q_f_2020_ is None:
rfr = self.foyer.revenu_fiscal_reference(s)
q_f = QuotientFamilial.nombre(self.foyer, s)
rev_q_f = QuotientFamilial.diviser(rfr, q_f, s)
impot_par_part_q_f = IR.montant_selon_revenu_2020(rev_q_f, s)
self.impot_avec_q_f_2020_ = QuotientFamilial.multiplier(impot_par_part_q_f, q_f).round_to_euro()
return self.impot_avec_q_f_2020_
def montant(self, s: Solver) -> Montant:
if self.montant_ is None:
self.montant_ = (self.calcul_avec_etapes(s))[4]
return self.montant_
def montant_2020(self, s: Solver) -> Montant:
if self.montant_2020_ is None:
self.montant_2020_ = (self.calcul_avec_etapes_2020(s))[3]
return self.montant_2020_
def calcul_avec_etapes(self, s: Solver) -> List[Montant]:
if self.calcul_avec_etapes_ is None:
impot_avec_q_f = self.impot_avec_q_f(s)
impot_sans_q_f = self.impot_sans_q_f(s)
q_f = QuotientFamilial.nombre(self.foyer, s)
q_f = QuotientFamilial2019.nombre(self.foyer, s)
out1 = Montant.anonyme(s, "ir_out1")
s.add(Implies(
......@@ -650,8 +577,8 @@ class IR:
rfr = self.foyer.revenu_fiscal_reference(s)
num = q_f.plafond_num_rscr.sub(rfr)
denom = Montant.anonyme(s, "denom_rscr")
s.add(Implies(self.foyer.une_personne(), denom == IR.denominateur_rscr_celibataire(s)))
s.add(Implies(self.foyer.deux_personnes(), denom == IR.denominateur_rscr_couple(s)))
s.add(Implies(self.foyer.une_personne(), denom == IR2019.denominateur_rscr_celibataire(s)))
s.add(Implies(self.foyer.deux_personnes(), denom == IR2019.denominateur_rscr_couple(s)))
rscr_bef = out2 % Taux.pourcent(20)
rscr_bef_big = Concat(BitVecVal(0, repr_bits), rscr_bef.valeur)
......@@ -680,54 +607,8 @@ class IR:
self.calcul_avec_etapes_ = [rfr, out1, decote_out, rscr, out]
return self.calcul_avec_etapes_
def calcul_avec_etapes_2020(self, s: Solver) -> List[Montant]:
if self.calcul_avec_etapes_2020_ is None:
impot_avec_q_f = self.impot_avec_q_f_2020(s)
impot_sans_q_f = self.impot_sans_q_f_2020(s)
q_f = QuotientFamilial.nombre(self.foyer, s)
out1 = Montant.anonyme(s, "ir_out1")
s.add(Implies(
impot_sans_q_f.sub(impot_avec_q_f) >= q_f.plafond_q_f,
And(out1 == impot_sans_q_f.sub(q_f.plafond_q_f),
self.plafonnement_q_f_actif)
))
s.add(Implies(
Not(impot_sans_q_f.sub(impot_avec_q_f) >= q_f.plafond_q_f),
And(out1 == impot_avec_q_f, Not(self.plafonnement_q_f_actif))
))
# Décote
decote = self.decote_2020(out1, s)
decote_out = Montant.anonyme(s, "decote_out")
s.add(Implies(decote <= out1, decote_out == decote))
s.add(Implies(decote > out1, decote_out == out1))
out2 = out1.sub(decote)
out3 = out2
out = Montant.anonyme(s, "ir_out")
ir_not_paid = out3 < Montant.euros(60, s)
s.add(Implies(ir_not_paid,
And(out == Montant.euros(0, s), self.non_prelemevement_actif)
))
s.add(Implies(Not(ir_not_paid),
And(out == out3, Not(self.non_prelemevement_actif))
))
rfr = self.foyer.revenu_fiscal_reference(s)
# Returns : rfr, droits_simples, decote, montant_final
self.calcul_avec_etapes_2020_ = [rfr, out1, decote_out, out]
return self.calcul_avec_etapes_2020_
class IRMenage:
class IRMenage2019:
def __init__(self, m: Menage):
self.menage = m
self.calcul_avec_etapes_: Optional[List[Montant]] = None
......@@ -742,8 +623,8 @@ class IRMenage:
decote = Montant.anonyme(s, "decote")
rscr = Montant.anonyme(s, "rscr")
out = Montant.anonyme(s, "ir")
bir1 = IR(self.menage.f1)
bir2 = IR(self.menage.f2)
bir1 = IR2019(self.menage.f1)
bir2 = IR2019(self.menage.f2)
[rfr1, ds1, decote1, rscr1, out1] = bir1.calcul_avec_etapes(s)
[rfr2, ds2, decote2, rscr2, out2] = bir2.calcul_avec_etapes(s)
s.add(Implies(
......@@ -765,39 +646,7 @@ class IRMenage:
self.calcul_avec_etapes_ = [rfr, ds, decote, rscr, out]
return self.calcul_avec_etapes_
def calcul_avec_etapes_2020(self, s: Solver) -> List[Montant]:
if self.calcul_avec_etapes_2020_ is None:
rfr = Montant.anonyme(s, "rfr")
ds = Montant.anonyme(s, "droits_simples")
decote = Montant.anonyme(s, "decote")
out = Montant.anonyme(s, "ir")
bir1 = IR(self.menage.f1)
bir2 = IR(self.menage.f2)
[rfr1, ds1, decote1, out1] = bir1.calcul_avec_etapes_2020(s)
[rfr2, ds2, decote2, out2] = bir2.calcul_avec_etapes_2020(s)
s.add(Implies(
self.menage.composition == Composition.concubinage(),
And(rfr == rfr1 + rfr2,
ds == ds1 + ds2,
decote == decote1 + decote2,
out == out1 + out2)
))
s.add(Implies(
Not(self.menage.composition == Composition.concubinage()),
And(rfr == rfr1,
ds == ds1,
decote == decote1,
out == out1)
))
self.calcul_avec_etapes_2020_ = [rfr, ds, decote, out]
return self.calcul_avec_etapes_2020_
def montant(self, s: Solver) -> Montant:
if self.montant_ is None:
self.montant_ = (self.calcul_avec_etapes(s))[4]
return self.montant_
def montant_2020(self, s: Solver) -> Montant:
if self.montant_2020_ is None:
self.montant_2020_ = (self.calcul_avec_etapes_2020(s))[3]
return self.montant_2020_
IR2020.py 0 → 100644
This diff is collapsed.
......@@ -20,7 +20,6 @@
from z3 import *
from montant import *
from foyerfiscal import *
from IR import *
from solveur import *
from individu import *
from prime_activite import *
......@@ -91,7 +90,7 @@ question_2019_2020 = Difference2019IR2020(
menage_constraints,
relative_true_absolue_false=True,
max_true_min_false=False,
initial_search_param_value=5,
initial_search_param_value=0,
lower_bound=-100,
upper_bound=20,
precision=1,
......
......@@ -20,7 +20,8 @@
from z3 import *
from montant import *
from foyerfiscal import *
from IR import *
from IR2019 import *
from IR2020 import *
from solveur import *
from individu import *
from prime_activite import *
......@@ -31,6 +32,8 @@ from typing import Set, Optional, List, Tuple, Union, Any
from verifisc_telegram_bot import post_message, post_file
from random_word import RandomWords # type: ignore
from questions import *
import subprocess
from tabulate import tabulate
def print_message(n: str, msg: str, send_to_telegram: bool) -> None:
......@@ -98,8 +101,10 @@ def dichotomic_search(
("Salaire annuel", s1, s2)
]
bir1 = IRMenage(m1)
bir2 = IRMenage(m2)
bir20191 = IRMenage2019(m1)
bir20192 = IRMenage2019(m2)
bir20201 = IRMenage2020(m1)
bir20202 = IRMenage2020(m2)
bam1 = AllocationsFamiliales(m1)
bam2 = AllocationsFamiliales(m2)
bapl1 = APL(m1)
......@@ -108,30 +113,43 @@ def dichotomic_search(
bpa2 = PrimeActivite(bam2, bapl2)
rev1 = s1
rev2 = s2
if "IR" in features:
[rfr1, droits_simples1, decote1, rscr1, ir1] = bir1.calcul_avec_etapes(s)
[rfr2, droits_simples2, decote2, rscr2, ir2] = bir2.calcul_avec_etapes(s)
if "IR2019" in features:
[rfr1, droits_simples1, decote1, rscr1, ir1] = bir20191.calcul_avec_etapes(s)
[rfr2, droits_simples2, decote2, rscr2, ir2] = bir20192.calcul_avec_etapes(s)
rev1 -= ir1
rev2 -= ir2
comparison_lines += [
("Revenu fiscal de référence", rfr1, rfr2),
("Droits simples", droits_simples1, droits_simples2),
("Décote", decote1, decote2),
("RSCR", rscr1, rscr2),
("IR", ir1, ir2),
("[2019] Revenu fiscal de référence", rfr1, rfr2),
("[2019] Droits simples", droits_simples1, droits_simples2),
("[2019] Décote", decote1, decote2),
("[2019] RSCR", rscr1, rscr2),
("[2019] IR", ir1, ir2),
]
if "IR2020" in features:
[rfr1, droits_simples1, decote1, rscr1, ir1] = bir20201.calcul_avec_etapes(s)
[rfr2, droits_simples2, decote2, rscr2, ir2] = bir20202.calcul_avec_etapes(s)
rev1 -= ir1
rev2 -= ir2
comparison_lines += [
("[2020] Revenu fiscal de référence", rfr1, rfr2),
("[2020] Droits simples", droits_simples1, droits_simples2),
("[2020] Décote", decote1, decote2),
("[2020] RSCR", rscr1, rscr2),
("[2020] IR", ir1, ir2),
]
if "2019IR2020" in features:
[rfr1, droits_simples1, decote1, rscr1, ir1] = bir1.calcul_avec_etapes(s)
[rfr2, droits_simples2, decote2, ir2] = bir2.calcul_avec_etapes_2020(s)
[rfr1, droits_simples1, decote1, rscr1, ir1] = bir20191.calcul_avec_etapes(s)
[rfr2, droits_simples2, decote2, ir2] = bir20202.calcul_avec_etapes(s)
rev1 -= ir1
rev2 -= ir2
comparison_lines += [
("Revenu fiscal de référence", rfr1, rfr2),
("Droits simples", droits_simples1, droits_simples2),
("Décote", decote1, decote2),
("RSCR", rscr1, Montant.euros(0, s)),
("IR", ir1, ir2),
("[2019-2020] Revenu fiscal de référence", rfr1, rfr2),
("[2019-2020] Droits simples", droits_simples1, droits_simples2),
("[2019-2020] Décote", decote1, decote2),
("[2019-2020] RSCR", rscr1, Montant.euros(0, s)),
("[2019-2020] IR", ir1, ir2),
]
# HYPOTHÈSE: Pas de non-recours aux allocations
if "AF" in features:
......
......@@ -19,7 +19,8 @@
from montant import *
from foyerfiscal import *
from IR import *
from IR2019 import *
from IR2020 import *
from solveur import *
from individu import *
from prime_activite import *
......
......@@ -22,13 +22,13 @@ from montant import *
from foyerfiscal import *
from menage import *
from individu import *
from IR import *
from typing import List, Tuple
from typing import List, Tuple, Any
import names # type: ignore
import datetime
from verifisc_telegram_bot import post_file
from os import mkdir
import subprocess
from tabulate import tabulate
def print_check_results_menage(
......@@ -110,4 +110,4 @@ def print_check_results_menage(
if post_to_telegram and c == sat:
post_file(filename)
return name.replace(" ", "_") + ".txt"
return name.replace(" ", "_") + ".txt" # type:ignore
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment