I am looking at some questions in my textbook about whether or not the variables are free or bound. I am not sure about these two in particular.
First off, I want to make sure I understand the concept of free vs. bound. I am fairly sure this x is a free variable in the following:
variable x is free in expression "x"
I believe this is true but I just want to make sure.
These two questions I am not really sure about, however.
(/ (+ 1 x) (let x 2 (+ x x))),
(let x y (/ (+ 1 x) (let x 2 (+ x x))))
For the top expression, the x in the first subexpression is unbound(right?) but x in the second subexpression is bound to 2, so would that mean the x in regards to the expression as a whole is unbound?
For the bottom expression, x is bound to y, but y is a free variable(?). So would x be free because y is free or is it bound because x is still bounded to y?
For (/ (+ 1 x) (let x 2 (+ x x))), the x in the first subexpression is unbound but x in the second subexpression is bound to 2, so would that mean the x in regards to the expression as a whole is unbound?
Yes. Although I would use the terminology "is bound" or "is free" only with respect to a concrete variable expression, not to a name. As you can see, it's ambiguous what "x" refers to.
I'd say "the whole expression has a free variable x", which is what you usually care about when trying to evaluate the expression.
For (let x y (/ (+ 1 x) (let x 2 (+ x x)))), x is bound to y, but y is a free variable. So would x be free because y is free or is it bound because x is still bounded to y?
The x is bound (and can be substituted). y is free.
Related
When using mixed assert and assert-soft in optimization tasks, e.g. maximize, the soft assertions are disregarded, if they would lead to a non-optimal result.
Is it possible to restrict the "softness" to the satisfiability search only? I.e.: If the soft assertion is satisfiable at all, it is kept and then treated as "hard" assertion in the optimization?
Example exhibiting the aforementioned:
(declare-fun x () Int)
(declare-fun y () Int)
(assert (< (+ x y) (* x y)))
(assert (>= x 0))
(assert (>= y x))
;(assert-soft (>= (* 4 x) y)); x->2, y->500
(assert (>= (* 4 x) y)); x->16, y->62
(assert (<= (* x y) 1000))
(maximize (+ x y))
(set-option :opt.priority pareto)
(check-sat)
(get-value (x y (+ x y) (* x y)))
(check-sat)
(get-value (x y (+ x y) (* x y)))
;...
This would be required to fulfill the following use case:
Given a complex fixed ruleset on a large (>1000) number of variables (mostly having a finite domain), a user can choose the desired values for any of those, which may lead to conflicts with the ruleset.
The individual values for a variable have ratings/weights.
So, given a set of user-selected (possibly conflicting) selections, the ruleset itself and finally the ratings of the set of all possible selections, one solution for all variables is to be found, which, while respecting all non-conflicting selections by the user, maximizes the total rating score.
I had the idea of using assert-soft for user selections to cancel out conflicting ones, while combining it with the optimization of z3 to get the "best" solution. However, this failed, which is the reason for this question.
My answer is yes, if you do it incrementally.
Assume that the set of soft-clauses has only a unique Boolean assignment which makes its associated MaxSMT problem optimal.
Then, it is easy to make satisfiable soft-clauses hard by fixing the value of the associated objective function. Although z3 does not allow to put explicit constraints on the name of a soft clause group (AFAIK), one can do it implicitly by using a lexicographic multi-objective combination rather than a pareto one.
Now, in your example we can safely switch from pareto to lexicographic search because there is only one extra objective function in addition to the one implicitly defined by assert-soft. Assuming the value of the assert-soft group being fixed, the whole problem degenerates to a single-objective formula which in turn has always at-most-one Pareto-optimal solution.
Of course, this is not possible if one plans to add more objectives to the formula. In this case, the only option is to solve the formula incrementally, as follows:
(set-option:produce-models true)
(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun LABEL () Bool)
(assert (and
(or (not LABEL) (>= (* 4 x) y))
(or LABEL (not (>= (* 4 x) y)))
)) ; ~= LABEL <-> (>= (* 4 x) y)
(assert-soft LABEL)
(assert (< (+ x y) (* x y)))
(assert (>= x 0))
(assert (>= y x))
(assert (>= (* 4 x) y))
(assert (<= (* x y) 1000))
(check-sat)
(get-model)
(push 1)
; assert LABEL or !LABEL depending on its value in the model
(maximize (+ x y))
; ... add other objective functions ...
(set-option :opt.priority pareto)
(check-sat)
(get-value (x y (+ x y) (* x y)))
(check-sat)
(get-value (x y (+ x y) (* x y)))
...
(pop 1)
This solves the MaxSMT problem first, fixes the Boolean assignment of the soft-clauses in a way that makes them hard, and then proceeds with optimizing multiple objectives with the pareto combination.
Note that, if the MaxSMT problem admits multiple same-weight solutions for the same optimal value, then the previous approach would discard them and focus on only one assignment. To circumvent this, the ideal solution would be to fix the value of the MaxSMT objective rather than fixing its associated Boolean assignment, e.g. as follows:
(set-option:produce-models true)
(declare-fun x () Int)
(declare-fun y () Int)
(declare-fun LABEL () Bool)
(assert-soft (>= (* 4 x) y) :id soft)
(assert (< (+ x y) (* x y)))
(assert (>= x 0))
(assert (>= y x))
(assert (>= (* 4 x) y))
(assert (<= (* x y) 1000))
(minimize soft)
(check-sat)
(get-model)
(push 1)
; assert `soft` equal to its value in model, e.g.:
; (assert (= soft XXX )))
(maximize (+ x y))
; ... add other objective functions ...
(set-option :opt.priority pareto)
(check-sat)
(get-value (x y (+ x y) (* x y)))
(check-sat)
(get-value (x y (+ x y) (* x y)))
...
(pop 1)
At the time being, this kind of syntax for objective combination is supported by OptiMathSAT only. Unfortunately, OptiMathSAT does not yet support non-linear arithmetic in conjunction with optimization, so it can't be reliably used on your example.
Luckily, one can still use this approach with z3!
If there is only one extra objective function in addition to the group of soft-clauses, one can still use the lexicographic combination rather than pareto one and get the same result.
Otherwise, if there are multiple objectives in addition to the group of soft-clauses, it suffices to explicitly encode the MaxSMT problem with a Pseudo-Boolean objective as opposed to using the assert-soft command. In this way, one retains full control of the associated objective function and can easily fix its value to any number. Note, however, that this might decrease the performance of the solver in dealing with the formula depending on the quality of the MaxSMT encoding.
I need to rely on the fact that two Z3 variables
can not have the same name.
To be sure of that,
I've used tuple_example1() from test_capi.c in z3/examples/c and changed the original code from:
// some code before that ...
x = mk_real_var(ctx, "x");
y = mk_real_var(ctx, "y"); // originally y is called "y"
// some code after that ...
to:
// some code before that ...
x = mk_real_var(ctx, "x");
y = mk_real_var(ctx, "x"); // but now both x and y are called "x"
// some code after that ...
And (as expected) the output changed from:
tuple_example1
tuple_sort: (real, real)
prove: get_x(mk_pair(x, y)) = 1 implies x = 1
valid
disprove: get_x(mk_pair(x, y)) = 1 implies y = 1
invalid
counterexample:
y -> 0.0
x -> 1.0
to:
tuple_example1
tuple_sort: (real, real)
prove: get_x(mk_pair(x, y)) = 1 implies x = 1
valid
disprove: get_x(mk_pair(x, y)) = 1 implies y = 1
valid
BUG: unexpected result.
However, when I looked closer, I found out that Z3 did not really fail or anything, it is just a naive (driver) print out to console.
So I went ahead and wrote the exact same test with y being an int sort called "x".
To my surprise, Z3 could handle two variables with the same name when they have different sorts:
tuple_example1
tuple_sort: (real, real)
prove: get_x(mk_pair(x, y)) = 1 implies x = 1
valid
disprove: get_x(mk_pair(x, y)) = 1 implies y = 1
invalid
counterexample:
x -> 1.0
x -> 0
Is that really what's going on? or is it just a coincidence??
Any help is very much appreciated, thanks!
In general, SMT-Lib does allow repeated variable names, so long as they have different sorts. See page 27 of the standard. In particular, it says:
Concretely, a variable can be any symbol, while a function symbol
can be any identifier (i.e., a symbol or an indexed symbol). As a
consequence, contextual information is needed during parsing to know
whether an identifier is to be treated as a variable or a function
symbol. For variables, this information is provided by the three
binders which are the only mechanism to introduce variables. Function
symbols, in contrast, are predefined, as explained later. Recall that
every function symbol f is separately associated with one or more
ranks, each specifying the sorts of f’s arguments and result. To
simplify sort checking, a function symbol in a term can be annotated
with one of its result sorts σ. Such an annotated function symbol is a
qualified identifier of the form (as f σ).
Also on page 31 of the same document, it further clarifies "ambiguity" thusly:
Except for patterns in match expressions, every occurrence of an
ambiguous function symbol f in a term must occur as a qualified
identifier of the form (as f σ) where σ is the intended output sort of
that occurrence
So, in SMT-Lib lingo, you'd write like this:
(declare-fun x () Int)
(declare-fun x () Real)
(assert (= (as x Real) 2.5))
(assert (= (as x Int) 2))
(check-sat)
(get-model)
This produces:
sat
(model
(define-fun x () Int
2)
(define-fun x () Real
(/ 5.0 2.0))
)
What you are observing in the C-interface is essentially a rendering of the same. Of course, how much "checking" is enforced by the interface is totally solver specific as SMT-Lib says nothing about C API's or API's for other languages. That actually explains the BUG line you see in the output there. At this point, the behavior is entirely solver specific.
But long story short, SMT-Lib does indeed allow two variables have the same name used so long as they have different sorts.
This question is subsequent to another one I posted earlier on custom labeling in Prolog.
Does the contracting/1 predicate, when used after a value assignment to a variable in a custom labeling predicate, delete the "inconsistent" values from the domain permanently ? Or are these values restored when backtracking ?
These values are of course restored on backtracking.
It is the nature of pure Prolog predicates, such as CLP(FD) constraints, that everything they state is completely undone on backtracking. Without this, many important declarative properties would not hold. See logical-purity for more information.
You can see easily that this also holds for clpfd:contracting/1, using for example a sample session:
?- X in 0..5, X mod Y #= 2, Y in 0..2.
X in 0..5,
X mod Y#=2,
Y in 1..2.
?- X in 0..5, X mod Y #= 2, Y in 0..2, clpfd:contracting([X,Y]).
false.
?- X in 0..5, X mod Y #= 2, Y in 0..2, ( clpfd:contracting([X,Y]) ; true ).
X in 0..5,
X mod Y#=2,
Y in 1..2.
I apologize in advance for this likely silly question :)
Suppose, I have a list of strings like
(define func-names '("add" "sub" "mul"))
And there are also functions defined like so
(define (add x y)
(+ x y))
(define (sub x y)
(- x y))
(define (mul x y)
(* x y))
As you can see, values of the strings in the list correspond to the names of the functions.
I need a way to iterate through the list and call the function that corresponds to a string value. Something like
(define (all-ops x y)
(map (lambda (name) (string->proc name x y)) func-names))
where string->proc is what I'm looking for. Something like Ruby's send/public_send method, if you're familiar with Ruby.
I'm mostly interested in answers applicable to Racket.
Thank you.
EDIT;
And I've forgotten to mention that there may be a million of function names, so cond, match would be tedious to use here.
Consider making a hash table that maps strings to function values.
That said, you can do as follows:
#lang racket
(define (add x y)
(+ x y))
(define ns (variable-reference->namespace (#%variable-reference)))
(define (string->procedure s)
(define sym (string->symbol s))
(eval sym ns))
(string->procedure "add")
((string->procedure "add") 1 2)
See also http://blog.racket-lang.org/2011/10/on-eval-in-dynamic-languages-generally.html
For the code below, I am unable to comprehend how the bindings (x, y, z) occur. Please check out the code, I'll explain my problem in greater detail below:
(define (w x)
(lambda (y z)
(begin
(set! x (+ (* y x) z)) x)))
(define f1 (w 3))
(f1 4 2)
(f1 2 1)
The output is 14, 29. These are values for x.
This means initially, x=3, y=4, z=2. In the 2nd call, i.e. (f1 2 1), x=14, y=2,z=1.
My doubts:
How does the binding occur at first, why is x=3, y=4, and z=2? If it has got to do with lambda expression in the function, please elaborate on how it works..I have a feeling this is where my understanding breaks down..
Next, why is the initial answer of x=14 retained in the second call, i.e. (f1 2 1)?
Thank you for looking into this :)
When w is run, it creates a closure out of the inner lambda. Because x came from outside of that inner lambda, x is stored inside that closure (in this case, f1).
So, f1 has a variable inside that represents x, and it starts out as 3. When you run f1, it evaluates the math and then sets its own x to be 14.
The moral is, a lambda is more than just code; it's code combined with the variables it closes over, such as this x.