Defining multiple constant variables in clojure - variables

I'm trying to define several constant variables in clojure. Is there a way to define all of them in one def statement? Or must I define each one separately?
In any programming language (C++ Java) you may expect to be able to do the following
const int x, y, z;
x = y = z = 0;
However, in clojure I'm having trouble doing something similar with the def declaration. I've tried something based off of the 'let' syntax:
(def ^:const [x 2 y 3 z 8])
and something like
(def ^:const x 2 y 3 z 8)
but none of these work. Must I separately define each variable?

If you want a separate Var for x, y, and z, you must define each one separately:
(def x 2)
(def y 3)
(def z 8)
You could easily write a macro to define multiple constants at once if this is too cumbersome:
(defmacro defs
[& bindings]
{:pre [(even? (count bindings))]}
`(do
~#(for [[sym init] (partition 2 bindings)]
`(def ~sym ~init))))
(defs x 2 y 3 z 8)
If these three constants are related, though, you could instead define a map with an entry for each number:
(def m {:x 2, :y 3, :z 8})
Depending on your use case, you may even find it valuable to define them as a vector instead:
(def v [2 3 8])

Related

Unique variable names in Z3

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.

Does the predicate `contracting/1` restore deleted inconsistent values?

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.

How to rename a variable which respects the name scope?

Given x, y are tensors, I know I can do
with tf.name_scope("abc"):
z = tf.add(x, y, name="z")
So that z is named "abc/z".
I am wondering if there exists a function f which assign the name directly in the following case:
with tf.name_scope("abc"):
z = x + y
f(z, name="z")
The stupid f I am using now is z = tf.add(0, z, name="z")
If you want to "rename" an op, there is no way to do that directly, because a tf.Operation (or tf.Tensor) is immutable once it has been created. The typical way to rename an op is therefore to use tf.identity(), which has almost no runtime cost:
with tf.name_scope("abc"):
z = x + y
z = tf.identity(z, name="z")
Note however that the recommended way to structure your name scope is to assign the name of the scope itself to the "output" from the scope (if there is a single output op):
with tf.name_scope("abc") as scope:
# z will get the name "abc". x and y will have names in "abc/..." if they
# are converted to tensors.
z = tf.add(x, y, name=scope)
This is how the TensorFlow libraries are structured, and it tends to give the best visualization in TensorBoard.
It seems it works also without tf.name_scope only with z = tf.identity(z, name="z_name"). If you run additionally z = tf.identity(z, name="z_name_new") then you can access the same tensor using both names: tf.get_default_graph().get_tensor_by_name("z_name:0") or tf.get_default_graph().get_tensor_by_name("z_name_new:0")

":=" and "=>" in Mercury

I recently came across this code example in Mercury:
append(X,Y,Z) :-
X == [],
Z := Y.
append(X,Y,Z) :-
X => [H | T],
append(T,Y,NT),
Z <= [H | NT].
Being a Prolog programmer, I wonder: what's the difference between a normal unification =
and the := or => which are use here?
In the Mercury reference, these operators get different priorities, but they don't explain the difference.
First let's re-write the code using indentation:
append(X, Y, Z) :-
X == [],
Z := Y.
append(X, Y, Z) :-
X => [H | T],
append(T, Y, NT),
Z <= [H | NT].
You seem to have to indent all code by four spaces, which doesn't seem to work in comments, my comments above should be ignored (I'm not able to delete them).
The code above isn't real Mercury code, it is pseudo code. It doesn't make sense as real Mercury code because the <= and => operators are used for typeclasses (IIRC), not unification. Additionally, I haven't seen the := operator before, I'm not sure what is does.
In this style of pseudo code (I believe) that the author is trying to show that := is an assignment type of unification where X is assigned the value of Y. Similarly => is showing a deconstruction of X and <= is showing a construction of Z. Also == shows an equality test between X and the empty list. All of these operations are types of unification. The compiler knows which type of unification should be used for each mode of the predicate. For this code the mode that makes sense is append(in, in, out)
Mercury is different from Prolog in this respect, it knows which type of unification to use and therefore can generate more efficient code and ensure that the program is mode-correct.
One more thing, the real Mercury code for this pseudo code would be:
:- pred append(list(T)::in, list(T)::in, list(T)::out) is det.
append(X, Y, Z) :-
X = [],
Z = Y.
append(X, Y, Z) :-
X = [H | T],
append(T, Y, NT),
Z = [H | NT].
Note that every unification is a = and a predicate and mode declaration has been added.
In concrete Mercury syntax the operator := is used for field updates.
Maybe we are not able to use such operators like ':=' '<=' '=>' '==' in recent Mercury release, but actually these operators are specialized unification, according to the description in Nancy Mazur's thesis.
'=>' stands for deconstruction e.g. X => f(Y1, Y2, ..., Yn) where X is input and all Yn is output. It's semidet. '<=' is on the contrary, and is det. '==' is used in the situation where both sides are ground, and it is semidet. ':=' is just like regular assigning operator in any other language, and it's det. In older papers I even see that they use '==' instead of '=>' to perform a deconstruction. (I think my English is awful = x =)

Given a substitution S and list Xs, how to apply S to Xs

Suppose I have a substitution S and list Xs, where each variable occurring in Xs also occurs in S. How would I find the list S(Xs), i.e., the list obtained by applying the substitution S to the list Xs.
More concretely, I have a set of predicates and DCG rules that look something like
pat(P) --> seg(_), P, seg(_).
seg(X,Y,Z) :- append(X,Z,Y).
If I attempt to match a pattern P with variables against a list, I receive a substitution S:
?- pat([a,X,b,Y],[d,a,c,b,e,d],[]).
X = c,
Y = e
I want to apply the substitution S = {X = c, Y = e} to a list Xs with variables X and Y, and receive the list with substitutions made, but I'm not sure what the best way to approach the problem is.
If I were approaching this problem in Haskell, I would build a finite map from variables to values, then perform the substitution. The equivalent approach would be to produce a list in the DCG rule of pairs of variables and values, then use the map to find the desired list. This is not a suitable approach, however.
Since the substitution is not reified (is not a Prolog object), you can bind the list to a variable and let unification do its work:
?- Xs = [a,X,b,Y], pat(Xs,[d,a,c,b,e,d],[]).
Xs = [a, c, b, e],
X = c,
Y = e .
Edit: If you want to keep the original list around after the substitution, use copy_term:
?- Xs = [a,X,b,Y], copy_term(Xs,Ys), pat(Xs,[d,a,c,b,e,d],[]).
Xs = [a, c, b, e],
X = c,
Y = e,
Ys = [a, _G118, b, _G124] .