<p>This answer was provided by Pieter Wuille (@pwuille) on <a href="https://twitter.com/pwuille/status/1260267536207147008?s=20" rel="nofollow noreferrer">Twitter</a>.</p>

<p>Conceptually it doesn't make sense, because script conditions are monotonic. What would <code>and(pk(A),not(pk(B)))</code> mean? "B does not sign" is trivially satisfied; B would just never bother signing.</p>

<p>Similarly, <code>not(older(N))</code> would not mean <code>younger(N)</code>. There (intentionally) does not exist a way in script to express a younger-than condition (because it would mean a tx that invalidates itself). "not(older(N))" would just be "do not prove time is past N", also trivial.</p>

<p>For example, Miniscript <code>l:older(N)</code> translates to <code>IF 0 ELSE &lt;N&gt; CHECKSEQUENCEVERIFY</code>.</p>

<p>CSV and CLTV don't actually observe the time; they observe the nLocktime/nSequence field in the transaction. There wouldn't be any problems with having an ability in Script to make arbitrary (including less than, negation, ...) statements about them.</p>

<p>However, it would likely be pointless. The nSequence and nLocktime fields themselves do observe time, and can only express larger-than constraints. Bitcoin transaction validity should be monotonic: once valid, absent double-spend, they remain valid.</p>

<p>The alternative would be a logistical nightmare. All mempool transactions would need to be reevaluated every block. Reasoning about validity of unconfirmed transactions would be a pain (e.g. what if you're paid using a tx spending the output of a soon-to-be expired tx?)</p>

CC BY-SA 4.0
2020-05-12T21:58:31.000Z
2020-05-12T21:58:31.000Z
Michael Folkson
<p>This question was asked by Luke Childs (@lukechilds) on <a href="https://twitter.com/lukechilds/status/1260263035396030464?s=20" rel="nofollow noreferrer">Twitter</a>.</p>
<p>In Miniscript would it be possible to invert conditions with something like <code>not()</code>? Could you essentially create a <code>younger()</code> out of <code>not(older())</code>?</p>
<p>e.g. <code>or(and(pk(Alice),not(older(12960))),and(pk(Bob),older(12960)))</code></p>
<p>The UTXO ownership transfers from Alice to Bob after 90 days.</p>
<p>I see that that won't work because CHECKSEQUENCEVERIFY doesn't return a boolean. But why is being able to invalidate a condition or completely change the conditions after a certain point in time bad?</p>
<p>e.g.
X can only happen before N, Y can only happen after N</p>
<p>A related question on why unconfirmed transactions can't expire is <a href="https://bitcoin.stackexchange.com/questions/116926/why-doesnt-the-protocol-allow-unconfirmed-transactions-to-expire-at-a-given-hei/">here</a>.</p>

<script><miniscript>
With Miniscript why is it not possible to invert conditions with something like not()?
Michael Folkson
# With Miniscript why is it not possible to invert conditions with something like not()?

(Asked by: username_0 on 2020-05-12)

This question was asked by Luke Childs (@lukechilds) on [Twitter](https://twitter.com/lukechilds/status/1260263035396030464?s=20).

In Miniscript would it be possible to invert conditions with something like `not()`? Could you essentially create a `younger()` out of `not(older())`?

e.g. `or(and(pk(Alice),not(older(12960))),and(pk(Bob),older(12960)))`

The UTXO ownership transfers from Alice to Bob after 90 days.

I see that that won't work because CHECKSEQUENCEVERIFY doesn't return a boolean. But why is being able to invalidate a condition or completely change the conditions after a certain point in time bad?

e.g.
X can only happen before N, Y can only happen after N

A related question on why unconfirmed transactions can't expire is [here](https://bitcoin.stackexchange.com/questions/116926/why-doesnt-the-protocol-allow-unconfirmed-transactions-to-expire-at-a-given-hei/).

**Tags:** script, miniscript


---

## 1 answers

### Answer by username_0 on 2020-05-12. Score: 3 | Accepted answer

This answer was provided by Pieter Wuille (@pwuille) on [Twitter](https://twitter.com/pwuille/status/1260267536207147008?s=20).

Conceptually it doesn't make sense, because script conditions are monotonic. What would `and(pk(A),not(pk(B)))` mean? "B does not sign" is trivially satisfied; B would just never bother signing.

Similarly, `not(older(N))` would not mean `younger(N)`. There (intentionally) does not exist a way in script to express a younger-than condition (because it would mean a tx that invalidates itself). "not(older(N))" would just be "do not prove time is past N", also trivial.

For example, Miniscript `l:older(N)` translates to `IF 0 ELSE <N> CHECKSEQUENCEVERIFY`.

CSV and CLTV don't actually observe the time; they observe the nLocktime/nSequence field in the transaction. There wouldn't be any problems with having an ability in Script to make arbitrary (including less than, negation, ...) statements about them.

However, it would likely be pointless. The nSequence and nLocktime fields themselves do observe time, and can only express larger-than constraints. Bitcoin transaction validity should be monotonic: once valid, absent double-spend, they remain valid.

The alternative would be a logistical nightmare. All mempool transactions would need to be reevaluated every block. Reasoning about validity of unconfirmed transactions would be a pain (e.g. what if you're paid using a tx spending the output of a soon-to-be expired tx?)


---

