How can I update state inside a ctheorems environment?

In MWE below i have dictionary which i want to update every time Problem environment is created. I need this updated dictionary to use in FMT constructor.
The problem is that after updating the test_dict typst does not see the change.
I understand that test_dict.get() is equivalent to test_dict.at(here()), so i can assume that both dict_test.update() function and test_dict.get() are evaluated at location here(), which causes the problem.
However, i find it counterintuitive, because they still go after each other.
So the question is if there is a way to make test variable contain updated version of test_dict

UPD. Ok, i made it work by changing
let test = test_dict.get().at("some_array")
to
let test = context test_dict.get().at("some_array")
Now will try to figure out why it works
UPD2 Still need help, because now test is of type content and is useless

#import "@preview/ctheorems:1.1.3": *
#show: thmrules

// create test dictionary
#let test_dict = state("test",
  (
    "some_array": ()
  )
)

#let problem = thmenv(
  "problem",
  none,
  none,
  (name, number, body) => context {
    //get current problem number
    let number = thmcounters.get().at("counters").at("problem").at(0)
    //update test_dict
    test_dict.update(x => {
      let y = x
      //push "body" of problem into "some_array"
      y.at("some_array").push(body)
      return y
    })
    //now the next line of code is the problem
    // test_dict did get updated, 
    //but variable "test" does not contain updated version of it
    let test = test_dict.get().at("some_array")
    let title = text(emph("Problem")+str(number)+".")
    [
      #title #body\
      #test
    ]
 }
)

//This should output: Problem1. first problem
//                              (first problem)
#problem[first problem]

#context {
  test_dict.get()
}

Hi @Ilya, could you maybe try to revise your post’s title to be a complete question as per the question guidelines:

Good titles are questions you would ask your friend about Typst.

We hope by adhering to this, we make the information in this forum easy to find in the future. Thanks!

While I don’t use ctheorems in particular, your updates look like you’re running into this:

Maybe that helps you until someone with more experience with ctheorems responds.

Hi @Ilya - i fear i don’t understand what you want to achieve.

What should thmenv do?

Should it save the current problem (as passed as argument) to the dictionary and then print it in the given way?

Hi @Florian
What i wanted to achieve is to get updated version of test_dict withing the scope of thmenv constructor to then use it’s value as i wish
@SillyFreak and UNDRL pointed out that nested contexts should be used in and it works indeed.
The achievement :grinning: :

#import "@preview/ctheorems:1.1.3": *
#show: thmrules.with(qed-symbol: $square$)

#show link: it => {
  set text(fill:
    if (type(it.dest) == "label") { green } else { green }
  )
  it
}
#show ref: it => {
  link(it.target, it)
}

#let qa_text = state("qa",
  (:)
)

#let hyper_problem = thmenv(
  "problem",
  none,
  none,
  (name, number, body) => context {
    let number = thmcounters.get().at("counters").at("problem").at(0)
    let num_identifier = "problem"+str(number)
    qa_text.update(x => {
      let y = x
      y.insert(num_identifier, ("p_content": body))
      return y
    })
    context {
    let p_key = qa_text.final().at(num_identifier)
    let loc = if ("ans_content" in p_key.keys() and p_key.at("ans_content") != []) {<temploc>} else {<temploc2>}
    let num_rect = rect(
        stroke: none,
        inset: 0em,
        place(
          right,
          dx: -100% - 8pt,
          link(loc)[#text(
            str(number)+"."
          )])+body)
          [#num_rect]}
    }
)

#let answer = (ans_cnt) => context {
  let number = thmcounters.get().at("counters").at("problem").at(0)
  qa_text.update(x => {
    let y = x
    y.at("problem"+str(number)).insert("ans_content", ans_cnt)
    return y
  })
}

#hyper_problem[first problem]
#answer[answer to first problem]

#hyper_problem[second problem]

#context qa_text.get()

templocation <temploc>

temploc2 <temploc2>
2 Likes