Skip to contents

This vignette shows how to define observed responses with first_of(), all_of(), none_of(), and inhibit(). Use these helpers when a response is not a direct readout from a single accumulator.

## 
## Attaching package: 'AccumulatR'
## The following object is masked from 'package:stats':
## 
##     simulate

What a response rule does

An outcome rule states when an observed response should count as having happened. Common cases include:

  • one of several routes being able to generate it
  • several processes all being complete
  • the absence of some competing event
  • a stop-like process that can cancel an otherwise available response

The logical helpers encode those cases directly in the model definition.

The four main helpers

The main helpers are:

  • first_of(x, y) means the response can be generated by either x or y
  • all_of(x, y) means the response requires both x and y
  • none_of(x) means the response rule requires x not to happen
  • inhibit(x, y) means x would generate the response, but y can block it

first_of(): either route can generate the response

Use first_of() when one of several routes can generate the same response.

model_first <- race_spec() |>
  add_accumulator("word_route", "lognormal") |>
  add_accumulator("picture_route", "lognormal") |>
  add_outcome("target_detected", first_of("word_route", "picture_route")) |>
  finalize_model()

model_first$outcomes[[1]]$label
## NULL

all_of(): several things must all be true

Use all_of() when a response depends on several processes all being complete.

model_all <- race_spec() |>
  add_accumulator("encoding", "lognormal") |>
  add_accumulator("verification", "lognormal") |>
  add_outcome("confirmed_response", all_of("encoding", "verification")) |>
  finalize_model()

model_all$outcomes[[1]]$label
## NULL

none_of(): the response requires the competing event to be absent

Use none_of() when the rule itself requires an event not to happen.

model_none <- race_spec() |>
  add_accumulator("go", "lognormal") |>
  add_accumulator("stop", "lognormal") |>
  add_outcome("respond", all_of("go", none_of("stop"))) |>
  finalize_model()

model_none$outcomes[[1]]$label
## NULL

Here the absence of stop is part of the response definition.

inhibit(): the response is driven by one process and blocked by another

Use inhibit() when one process would generate the response and another can block it.

model_inhibit <- race_spec() |>
  add_accumulator("go", "lognormal") |>
  add_accumulator("stop", "lognormal") |>
  add_outcome("respond", inhibit("go", "stop")) |>
  finalize_model()

model_inhibit$outcomes[[1]]$label
## NULL

Here go is the response-generating process and stop blocks it.

none_of() versus inhibit()

These two rules look similar:

rule_none <- all_of("go", none_of("stop"))
rule_inhibit <- inhibit("go", "stop")

rule_none
## $kind
## [1] "and"
## 
## $args
## $args[[1]]
## $args[[1]]$kind
## [1] "event"
## 
## $args[[1]]$source
## [1] "go"
## 
## $args[[1]]$k
## NULL
## 
## 
## $args[[2]]
## $args[[2]]$kind
## [1] "not"
## 
## $args[[2]]$arg
## $args[[2]]$arg$kind
## [1] "event"
## 
## $args[[2]]$arg$source
## [1] "stop"
## 
## $args[[2]]$arg$k
## NULL
rule_inhibit
## $kind
## [1] "guard"
## 
## $blocker
## $blocker$kind
## [1] "event"
## 
## $blocker$source
## [1] "stop"
## 
## $blocker$k
## NULL
## 
## 
## $reference
## $reference$kind
## [1] "event"
## 
## $reference$source
## [1] "go"
## 
## $reference$k
## NULL

But they are not the same model statement.

all_of("go", none_of("stop"))

This defines the response in terms of two conditions: go happened and stop did not happen.

inhibit("go", "stop")

This defines go as the response-generating event and stop as a blocker of that event.

In short:

  • inhibit() means “stop can block go if it gets there in time”
  • none_of() means “the response requires stop not to occur”

A combined example

The helpers can be combined when a response depends on several kinds of logic at once. For example, suppose a response requires:

  • an encoding stage to finish
  • either a left route or a right route to generate the choice
  • no stop event
model_combo <- race_spec() |>
  add_accumulator("encoding", "lognormal") |>
  add_accumulator("left_route", "lognormal") |>
  add_accumulator("right_route", "lognormal") |>
  add_accumulator("stop", "lognormal") |>
  add_outcome(
    "choice",
    all_of(
      "encoding",
      first_of("left_route", "right_route"),
      none_of("stop")
    )
  ) |>
  finalize_model()

model_combo$outcomes[[1]]$label
## NULL

Use combined rules when the observed response reflects a structured decision rule rather than a single winning accumulator.

Choosing the right helper

As a practical guide:

  • use first_of() when several routes can each produce the same response
  • use all_of() when several conditions must all be satisfied
  • use none_of() when the response rule explicitly requires some event to be absent
  • use inhibit() when one process would produce the response and another process can cancel it

none_of() treats absence as part of the response definition. inhibit() treats one process as blocking another.