# Accessing prior bound value setarg

**URL:** <https://swi-prolog.discourse.group/t/accessing-prior-bound-value-setarg/4692>\
**Category:** Predicate\
**Created:** [November 30, 2021, 1:40am UTC](https://swi-prolog.discourse.group/t/accessing-prior-bound-value-setarg/4692 "2021-11-30T01:40:24Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [November 30, 2021, 1:40am UTC](https://swi-prolog.discourse.group/t/accessing-prior-bound-value-setarg/4692/1 "2021-11-30T01:40:24Z")

</div>

Hi,

Consider the following code:

```prolog
test_arg :-
      Term = f(_),
       setarg(1, Term, a),
       setarg(1, Term, b),
       setarg(1, Term, c),
      get_prior_val(Term, 1, Val1),
      get_prior_val(Term, 2, Val2),
      Val1 = b.
      Val2 = a.

```

Is it possible to obtain the prior val of Term, as suggested in the code above – i.e. to retrieve Term’s value in a prior frame …

I guess, something like this is possible, since in the debugger one can view the prior binding of variables by clicking on an earlier location in the execution stack …

How is it done?

I am mainly interested in this for testing purposes …

thanks,

Dan

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [November 30, 2021, 9:48am UTC](https://swi-prolog.discourse.group/t/accessing-prior-bound-value-setarg/4692/4 "2021-11-30T09:48:51Z")

</div>

sorry, fixed it – to setarg –

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [November 30, 2021, 9:51am UTC](https://swi-prolog.discourse.group/t/accessing-prior-bound-value-setarg/4692/6 "2021-11-30T09:51:53Z")

</div>

In the setarg docu it says:

" Extra-logical predicate. Assigns the Arg-th argument of the compound term Term with the given Value. _The assignment is undone if backtracking_ brings the state back into a position before the [setarg/3](https://www.swi-prolog.org/pldoc/man?predicate=setarg/3)"

So, this should behave quite similar to, say, assoc with a current and next state …

**put\_assoc** (+Key, +Assoc0, +Value, -Assoc)

My intent is to replace an assoc and related put\_assoc – which is a key value store – with setarg – which is an array – while relying on setargs backtracking:

Something like this:

```prolog
	global_struct(global(Arg1, Arg2), 
		Arg1, Arg2.

     set_arg1(Global, NewVal) :- setarg(Global, 1, NewVal).
     set_arg2(Global, NewVal) :- setarg(Global 2, NewVal).

     init_global(Global) :-
                      global_struct(Global), default_1, default_2).
                     
   goal_predicate(Global) :-
                    some further process ... that generates a New_Val
                    set_arg1(Global, New_Val),

```

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [November 30, 2021, 9:57am UTC](https://swi-prolog.discourse.group/t/accessing-prior-bound-value-setarg/4692/8 "2021-11-30T09:57:34Z")

</div>

I don’t understand exactlly where you are going so will not try to answer.

With regards to arg/3 the post: [Does SWI-Prolog have N+K-trees?](https://swi-prolog.discourse.group/t/does-swi-prolog-have-n-k-trees/1310) helped me learn a lot.

In particular the code from Jan W in this [reply](https://swi-prolog.discourse.group/t/does-swi-prolog-have-n-k-trees/1310/5).

The notes I took in learning to use it in this [reply](https://swi-prolog.discourse.group/t/does-swi-prolog-have-n-k-trees/1310/6).

HTH

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [November 30, 2021, 10:39am UTC](https://swi-prolog.discourse.group/t/accessing-prior-bound-value-setarg/4692/10 "2021-11-30T10:39:50Z")

</div>

> [@grossdan](#):
>
> I guess, something like this is possible, since in the debugger one can view the prior binding of variables by clicking on an earlier location in the execution stack …

Are you sure? Seems unlikely to me. Not clear what “earlier location in the execution stack” is anyway. Frames have parents, but the data you see in the parent is in the same state if it is shared with child frames.

> [@grossdan](#):
>
> How is it done?

Except for backtracking, there is no way to get the previous value. Of course you could implement that. It means scanning the trail until you find a trailed assignment into the target term. That is rather costly. Also, if the are two or more consecutive setarg/1 calls on the same location without a reachable choice point in between, only the first is preserved and the rest is reclaimed by the garbage collector.

If you want an argument with a history, the solution of @anon95304481 comes to mind. You could improve on that by using setarg/3 to keep _current_ value at the head. That approach keeps O(1) update and access time at a (small) cost of more expensive trailing by setarg/3 when compared to normal unification. E.g.

```prolog
fetch_arg(I, Term, Value) :-
    arg(I, Term, [Value|_History]).

update_arg(I, Term, Value) :-
    arg(I, Term, Old),
    setarg(I, Term, [Value|Old]).

```

Now you can easily access old values. The price is that the value is always embedded in a list. I don’t recall I ever wanted something like this 🙂

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [November 30, 2021, 10:59am UTC](https://swi-prolog.discourse.group/t/accessing-prior-bound-value-setarg/4692/11 "2021-11-30T10:59:33Z")

</div>

Thank you Jan,

Stepping back, I simply wanted to prove via a test that the prior values are preserved after a number of setarg calls – and would “pop” up during backtracking.

The global structure I currently have is based on assoc and hence always has the before and after assoc as argument (i don’t hide them via DCG/monads).

When i revised the code to use backtrackable setarg instead i noticed that only one Global variable is needed as argument – which reminded me of the variable implementation (via \<= and =\> operators) in logtalk.

But, i assumed that setarg manage the before and after internally – and hence wanted to see if i can test for them without triggering a backtracking.

Dan

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [November 30, 2021, 11:12am UTC](https://swi-prolog.discourse.group/t/accessing-prior-bound-value-setarg/4692/12 "2021-11-30T11:12:29Z")

</div>

After seeing the reply by Jan W. I think I see what you seek.

You want to be able to go back in time, an event, and retrieve the value for a term.

I have a similar problem.

While the list structure works, a problem you may encounter later is that you want to know the relationship of two values for a given event. Since the list does not record the event but only the value there is no way to sync up values, unless you add a value to the list for every event meaning that the list will contain an entry for every event and also hold lots of redundant data. So when I record the value I also record the term as you call it and the event, which for now is just a sequential number associated with each event. The data is not kept in a list but some data structures I use are [red-black trees](https://eu.swi-prolog.org/pldoc/doc/_SWI_/library/rbtrees.pl) or just [asserting facts](https://www.swi-prolog.org/pldoc/man?section=dynpreds). Yes, this code is not fast but as I often note get the code working correctly first then go after optimizations. The events are actually calls from prolog\_trace\_interception/4.

When the values are stored as dynamic predicates (facts) and the key, think key value pair, is both the name and event, then a query returns more than just one item for a name. So to get the last value for a name aggregate/3 is used with a `max` operator.

The point is that until you get to a real world problem with this, there is more to think about than what you asked.

If I understand [Terminus DB](https://terminusdb.com/), this is their ball game.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [November 30, 2021, 12:44pm UTC](https://swi-prolog.discourse.group/t/accessing-prior-bound-value-setarg/4692/14 "2021-11-30T12:44:57Z")

</div>

Thanks.

Yes, i also looked at prolog\_trace\_interception but didn’t really understand what it does, and how to make use of it.

Ideally, it would be nice to have a way to peek into the inter workings in an easy way – like those CPU emulators that show you registers memory and ALU and control units that do things …

Would actually very nice to have for Prolog as well …

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [November 30, 2021, 2:55pm UTC](https://swi-prolog.discourse.group/t/accessing-prior-bound-value-setarg/4692/17 "2021-11-30T14:55:54Z")

</div>

I now noticed how destructive setarg is 🙂

It changes the argument also earlier in the stack in the debug window.

I will look at a different approach, taken from the Crafts book, where avoid setarg and update the “Context Argument” structure by binding an update to another variable like so:

```prolog
set_global_structure_arg1(global(Arg1, Arg2), New_Global, New_Arg1) :-
           New_Global = global(New_Arg1, Arg2).

```

Like this i am assured that a new version is created while i can continue to see the old values higher up in the call stack.

I guess overall the setarg version might be faster given its destructiveness – less copying … so, i could go for it later on, if i need to try to increase performance … and given the frequency this call is going to be made.
