ajar.afdm.AFDM#
- class ajar.afdm.AFDM[source]#
Bases:
object
An Argumentation Framework for Decision-Making.
An AFDM contains arguments, and an attack (binary) relationship between arguments. It can be used to compute the grounded extension of arguments in a given situation (i.e., with only certain arguments activated).
Methods
__init__
()Create a new AFDM.
add_argument
(argument)Add a new argument to the known arguments.
add_attack_relation
(attacker, attacked)Add a new attack between arguments.
arguments_countering
(decision[, ...])Return the arguments that counter a given decision.
arguments_supporting
(decision[, ...])Return the arguments that support a given decision.
Compute the grounded extension.
get_attacked
(argument[, return_arguments])Return the arguments that are attacked by a given argument.
get_attackers
(argument[, return_arguments])Return the arguments that are attackers of a given argument.
is_alive
(argument_name)Return whether an argument is alive in this AFDM.
Compute the grounded extension and update the arguments' aliveness.
Attributes
All attack relations known in this AFDM.
All arguments known in this AFDM.
The map of known arguments, indexed by their name for faster access.
A dictionary mapping arguments to their attackers.
A dictionary mapping arguments to the arguments that they attack.
The set of known decisions.
The list of arguments' names that are in the grounded extension at the current step.
- A: Dict[str, Argument]#
The map of known arguments, indexed by their name for faster access.
To iterate over arguments, please see
arguments
.
- property R: Iterable[Attack]#
All attack relations known in this AFDM.
To simplify usage and enforce types, attacks are represented by the Attack dataclass. In the comments, we will also note them as tuples, e.g.,
('a', 'b')
means that argument'a'
attacks'b'
.This should be used to iterate over all attacks, but not when accessing the attackers of a specific argument (or, conversely, the arguments attacked by a specific argument). For these operations, the optimized way is to use the
get_attackers()
andget_attacked()
methods, which internally use MultiMaps for performance.
- _grounded_loop_condition(labels: Dict[str, str]) str | None [source]#
Find the next candidate for the grounded extension.
Internal method that should not be useful externally. It finds an argument which is still
undecided
, and for which all attackers have been killed (out
), i.e., a suitable candidate for the grounded extension.- Parameters:
labels – The arguments’ labels when computing the grounded, i.e., a dictionary mapping each argument name to a label (
undecided
,in
, orout
).- Returns:
A new candidate argument, identified by its name, or
None
if there is no remaining candidate (i.e., the grounded is complete).
- add_argument(argument: Argument) Argument [source]#
Add a new argument to the known arguments.
- Parameters:
argument – The argument to add. If an argument with the same name already exists, a warning is raised, and the new argument overrides the previous one. The argument is deep-copied before it is added, so that this AFDM can be modified without any side effect on other AFDMs, if they share arguments.
- Returns:
The new argument, which is a deep-copy of the given one.
- add_attack_relation(attacker: str | Argument, attacked: str | Argument)[source]#
Add a new attack between arguments.
- Parameters:
attacker – The attacker argument, either identified by its name, or the argument itself.
attacked – The attacked argument, either identified by its name, or the argument itself.
- Raises:
An exception is raised if the arguments’ names (either passed directly as parameters, or obtained through the arguments themselves) are not known, i.e., no argument is associated to them in this AFDM builder.
- property arguments: Iterable[Argument]#
All arguments known in this AFDM.
This is a shortcut to
self.A.values()
, allowing to access the arguments themselves (not the dict) easily.
- arguments_countering(decision: str, ignore_aliveness: bool = False) List[Argument] [source]#
Return the arguments that counter a given decision.
This function corresponds to the
F_c
set in our algorithm, and is mostly used to get the number of countering arguments, comparing it to the number of supporting arguments, and resulting in a scalar reward. Optionally, returns all arguments, even those that are “killed” (not alive).- Parameters:
decision – The decision that we are looking for. Typically,
'moral'
.ignore_aliveness – Whether to return only alive arguments (by default), or to ignore the aliveness and return all arguments supporting
decision
(when set toTrue
).
- Returns:
The list of arguments that counter
decision
, i.e., that havedecision
as part of theircounter
. Whenignore_aliveness
isFalse
, only arguments that have theiralive
set toTrue
are returned. Otherwise, this condition is ignored.
- arguments_supporting(decision: str, ignore_aliveness: bool = False) List[Argument] [source]#
Return the arguments that support a given decision.
This function corresponds to the
F_f
set in our algorithm, and is mostly used to get the number of supporting arguments, comparing it to the number of countering arguments, and resulting in a scalar reward. Optionally, returns all arguments, even those that are “killed” (not alive).- Parameters:
decision – The decision that we are looking for. Typically,
'moral'
.ignore_aliveness – Whether to return only alive arguments (by default), or to ignore the aliveness and return all arguments supporting
decision
(when set toTrue
).
- Returns:
The list of arguments that support
decision
, i.e., that havedecision
as part of theirsupport
. Whenignore_aliveness
isFalse
, only arguments that have theiralive
set toTrue
are returned. Otherwise, this condition is ignored.
- attacked: Dict[str, Set[str]]#
A dictionary mapping arguments to the arguments that they attack.
In other words,
attacked[x] = { y, z }
means thatx
attacksy
andz
. More generally, it should be read asattacked[attacker] = set of attacked arguments
.This structure (dict of sets) is also known as a MultiMap (or MultiSet), and is optimal for performances, when getting all attacked arguments of a given argument, instead of iterating over the whole list of attack relations. The
get_attacked()
method offers is the public interface for getting attackers in an easy way (and also allows to return Arguments instead of their names).Warning
This field should never be modified directly! Otherwise, the
attackers
attribute would not be updated, and the attack relationship would not be correctly set. Please use theadd_attack_relation()
method instead, which ensures both attribute are modified.
- attackers: Dict[str, Set[str]]#
A dictionary mapping arguments to their attackers.
In other words,
attackers[x] = { y, z }
mean thaty
andz
are attackers ofx
. More generally, it should be read as:attackers[attacked] = set of attackers
.This structure (dict of sets) is also known as a MultiMap (or MultiSet), and is optimal for performances, when getting all attackers of a given argument, instead of iterating over the whole list of attack relations. The
get_attackers()
method offers is the public interface for getting attackers in an easy way (and also allows to return Arguments instead of their names).Warning
This field should never be modified directly! Otherwise, the
attacked
attribute would not be updated, and the attack relationship would not be correctly set. Please use theadd_attack_relation()
method instead, which ensures both attribute are modified.
- compute_grounded_extension() List[str] [source]#
Compute the grounded extension.
The grounded extension is one of the ways of computing the acceptable set of arguments, based on attacks between them.
- Returns:
The list of names of arguments that are in the grounded extension, i.e., which are considered acceptable.
- decisions: Set[str]#
The set of known decisions.
Decisions are retrieved from the arguments’
support
andcounter
fields. As mentioned in their docs, in our current version, decisions are not really used. In practice, the default'moral'
decision will be the only one, i.e., arguments support or counter “The agent’s last action was moral with respect to the given moral value”.
- get_attacked(argument: Argument | str, return_arguments=False) List[str] | List[Argument] [source]#
Return the arguments that are attacked by a given argument.
- Parameters:
argument – The desired argument, or its
name
.return_arguments – Whether to return the attacked as arguments directly, or to return their names.
- Returns:
The list of arguments that are attacked by
argument
, i.e., the arguments with namea
such that(argument, 'a')
are inR
. Whenreturn_arguments
isTrue
, the returned list is composed of instances of Arguments; otherwise, it is composed of the arguments’ names (strings).
- get_attackers(argument: Argument | str, return_arguments=False) List[str] | List[Argument] [source]#
Return the arguments that are attackers of a given argument.
- Parameters:
argument – The desired argument, or its
name
.return_arguments – Whether to return the attackers as arguments directly, or to return their names.
- Returns:
The list of arguments that attack
argument
, i.e., the arguments with namea
such that('a', argument)
are inR
. Whenreturn_arguments
isTrue
, the returned list is composed of instances of Arguments; otherwise, it is composed of the arguments’ names (strings).
- grounded: List[str]#
The list of arguments’ names that are in the grounded extension at the current step.
The grounded extension must be re-computed each step, by taking into account the new situation, and thus the new aliveness of arguments.
- is_alive(argument_name: str) bool [source]#
Return whether an argument is alive in this AFDM.
This is a shortcut for
self.A[argument_name].alive
, which also makes the error more explicit if the argument cannot be found.- Parameters:
argument_name – The name of the desired argument. Must be a valid key in
A
, otherwise an Exception is raised.- Returns:
The argument’s aliveness.
- update_alive_in_grounded_extension()[source]#
Compute the grounded extension and update the arguments’ aliveness.
The grounded extension is computed based on arguments that are alive or not, and attacks. Then, the arguments are said to be alive if they are in the grounded; otherwise, they are not.
This method thus transitions from “activated arguments” (i.e., arguments that are true in the given situation) to “acceptable arguments” (i.e., arguments that are true and defend each other).