Why is CVC4 product operator not applying to sets? - smt

I am tinkering with CVC4 support for sets and relations and expected to be able to use the product operator to build the Cartesian product of two sets. However, this operator only applies to relations.
This is a sample input fed to CVC4:
(set-logic ALL_SUPPORTED)
(declare-sort S1 0)
(declare-sort S2 0)
(declare-fun es1 () (Set S1))
(declare-fun es2 () (Set S2))
(declare-fun es1s2 () (Set (Tuple S1 S2)))
(assert (= es1s2 (product es1 es2)))
This results in the following error message:
(error " Relational operator operates on non-relations (sets of tuples)")
I then found that CVC4 expects the product operator to apply to sets of tuples. The following is processed successfully:
(set-logic ALL_SUPPORTED)
(declare-sort S1 0)
(declare-sort S2 0)
(declare-fun e1 () (Set (Tuple S1)))
(declare-fun e2 () (Set (Tuple S2)))
(declare-fun es1s2 () (Set (Tuple S1 S2)))
(assert (= es1s2 (product e1 e2)))
CVC4 could consider here that a set as the set of 1-tuples with elements of that set.
Is there any fundamental issue that prevents it from having this behavior?

This is just how the syntax works in CVC4. I am using it for work, and we specifically deal with the Theory of Sets. For most of the operations on sets with Finite relations, CVC4 expects to have tuples.
This link may be helpful: https://cvc4.github.io/sets-and-relations
So, the operations with Finite Sets generally can be operated without tuples, while finite relations need tuples.
Also, I found this paper helps to understand the theory behind the implementation of set in CVC4: https://homepage.cs.uiowa.edu/~tinelli/papers/MenEtAl-CADE-17.pdf

Related

What does the expression (define (f x) (length (range 3000))) evaluate to?

For the expression
(define x (length (range 3000)))
I think it is evaluated to
(define x 3000)
For the expression
(define (f x) (length (range 3000)))
Does it evaluate to the following as well?
(define (f x) 3000)
No, they evaluate to two different procedures, with different bodies. A completely different matter is that when executed, they both will return the same value, namely 3000, ignoring the parameter in both cases. To be clear, the first expression binds f to a lambda (this is how define expands a procedure definition under the hood):
(define f
(lambda (x) (length (range 3000))))
The second expression also binds f to a lambda, but it's a different one:
(define f
(lambda (x) 3000))
Either one will return 3000 when invoked:
(f 42)
=> 3000
But the first one will do more work, it has to create a range and calculate its length, whereas the second one simply returns 3000. Regarding your first example - in the end x will have the same value, and it won't matter how you calculated it. But for the second example, the two fs are different objects, even though the values they calculate are the same.

Common Lisp: How to quote parenthese in SBCL

In Common Lisp, the special operator quote makes whatever followed by un-evaluated, like
(quote a) -> a
(quote {}) -> {}
But why the form (quote ()) gives me nil? I'm using SBCL 1.2.6 and this is what I got in REPL:
CL-USER> (quote ())
NIL
More about this problem: This is some code from PCL Chapter 24
(defun as-keyword (sym)
(intern (string sym) :keyword))
(defun slot->defclass-slot (spec)
(let ((name (first spec)))
`(,name :initarg ,(as-keyword name) :accessor ,name)))
(defmacro define-binary-class (name slots)
`(defclass ,name ()
,(mapcar #'slot->defclass-slot slots)))
When the macro expand for the following code:
(define-binary-class id3-tag
((major-version)))
is
(DEFCLASS ID3-TAG NIL
((MAJOR-VERSION :INITARG :MAJOR-VERSION :ACCESSOR MAJOR-VERSION)))
which is NIL rather than () after the class name ID3-TAG.
nil and () are two ways to express the same concept (the empty list).
Traditionally, nil is used to emphasize the boolean value "false" rather than the empty list, and () is used the other way around.
The Common LISP HyperSpec says:
() ['nil], n. an alternative notation for writing the symbol nil, used
to emphasize the use of nil as an empty list.
Your observation is due to an object to having more than one representation. In Common Lisp the reader (that reads code and reads expressions) parses text to structure and data. When it's data the writer can print it out again but it won't know exactly how the data was represented when it was initially read in. The writer will print one object exactly one way, following defaults and settings, even though there are several representations for that object.
As you noticed nil, NIL, nIL, NiL, ... ,'nil, 'NIL, (), and '() are all read as the very same object. I'm not sure the standard dictates exactly how it's default representation out should be so I guess some implementations choose one of NIL, nil or maybe even ().
With cons the representation is dependent on the cdr being a cons/nil or not:
'(a . nil) ; ==> (a)
'(a . (b . c)) ; ==> (a b . c)
'(a . (b . nil)) ; ==> (a b)
With numbers the reader can get hints about which base you are using. If no base is used in the text it will use whatever *read-base* is:
(let ((*read-base* 2)) ; read numbers as boolean
(read-from-string "(10 #x10)")) ; ==> (2 16)
#x tells the reader to interpret the rest as a hexadecimal value. Now if your print-base would have been 4 the answer to the above would have been visualized as (2 100).
To sum it up.. A single value in Common Lisp may have several good representations and all of them would yield the very same value. How the value is printed will follow both implementation, settings and even arguments to the functions that produce them. Neither what it accepts as values in or the different ways it can visualize the value tells nothing about how the value actually gets stored internally.

Lisp IF-THEN-ELSE Lambda Calc Implementation

I made this IF-THEN-ELSE Lambda Calculus code
(defvar IF-THEN-ELSE
#'(lambda(con)
#'(lambda(x)
#'(lambda(y)
#'(lambda(acc1)
#'(lambda (acc2)
(funcall (funcall (funcall (funcall con x) y) acc1) acc2))))))
)
(defun IF-THEN-ELSEOP(c x y a1 a2)
(funcall (funcall (funcall (funcall (funcall IF-THEN-ELSE c) x) y) a1) a2)
)
And this Greater or Equal operator
(defvar GEQ
#'(lambda(p)
#'(lambda(q)
(funcall #'LEQOP q p)))
)
LEQOP is a function for "Less or Equal" and it works OK. So when I call IF-THEN-ELSE like this ("six" and "two" are church numbers)
(if-then-elseop GEQ six two (print "THIS") (print "THAT"))
as output I've got
"THIS"
"THAT"
"THIS"
Both functions that I'm passing are being called. How can I avoid it in order to get only as output "THIS"?
This happens with every function I use, and this is a trouble because I want to use IF-THEN-ELSE in a recursive call, so just one function must be called dependign on the IF-THEN-ELSE eval.
Any help would be appreciated
Thanks.
Passing your print statements by wrapping them in lambdas should work, but maybe it's worth an explanation as to why this is necessary.
You're implementing a lambda calculus. By definition, all 'things' in the calculus are higher order functions. Your six and two and any other church numerals you may have defined are also higher order functions.
IF-THEN-ELSE is a lambda abstraction (also a higher-order function because it's 'arguments' are also functions). So this would have been valid:
(if-then-elseop GEQ six two one two)
Where one and two are church numbers. By doing that, you're expressing in lambda calculus what you would in plain lisp as:
(if (>= 6 2)
1
2)
But I'm guessing what you were aiming for was:
(if (>= 6 2)
(print "this")
(print "that"))
(more later about why messing with print might be a distraction to your exercise)
So the 'real' 1 has a church encoding one, which I'me assuming you've defined. That way, it can be applied to the lambda abstraction IF-THEN-ELSE - In the same way that
(>= 6 2)
evaluates to TRUE in the lisp world, your lambda calculus implementation of the same,
((GEQ six) two)
will evaluate to the lambda encoding of TRUE, which is again, encoded as a higher-order function.
(defvar TRUE #'(lambda (x) #'(lambda (y) x)))
(defvar FALSE #'(lambda (x) #'(lambda (y) y)))
So the rule to remember is that everything you are passing around and getting back in the lambda calculus are functions:
0 := λf.λx.x
1 := λf.λx.f x
2 := λf.λx.f (f x)
3 := λf.λx.f (f (f x))
... and so on
Which is why, if you did:
(if-then-elseop GEQ six two
#'(lambda () (print "THIS"))
#'(lambda () (print "THAT")))
should work. (sort of, read ahead)
(I'd stick to the faithful interpretation of IF-THEN-ELSE though:
(defvar IFTHENELSE
#'(lambda (p)
#'(lambda (a)
#'(lambda (b) (funcall (funcall p a) b)))))
Where p is your condition... )
As a side note, it's worth pointing out that it might not be too helpful to bring in print and other code that 'does stuff' within lambda calculus - the calculus does not define IO, and is restricted to evaluation of lambda expressions. The church encodings are a way of encoding numbers as lambda terms; There's no simple and meaningful way to represent
a statement with side-effects such a (print "hello") as a lambda term; #'(lambda () (print "THIS")) works but as an academic exercise it's best to stick to only evaluating things and getting back results.
What about lisp itself? if in lisp is not a function so (if cond then-expr else-expr) works the way you expect (that is, only one of then-expr or else-expr will actually be evaluated) because it is a special form. If you were to define your own, you would need a macro (as #wvxvw rightly suggests). But that's another topic.

How can I restrict the domain of a sort in Z3 to a single value?

I'm using the following rule in my Z3 program to make s the only possible value of sort S.
(assert (forall ((t S)) (= t s)))
However, the above formula makes Z3 report the following error:
Z3: ERROR: WARNING: failed to find a pattern for quantifier (quantifier id: k!8)
What is the right way to make sure that the domain of a particular sort has only a single value?
The message
Z3: ERROR: WARNING: failed to find a pattern for quantifier (quantifier id: k!8)
is misleading. This is just an warning, the “ERROR” word is there by accident. This was fixed, and will be available in the next release.
The warning just tells the user that the E-matching module will ignore the quantifier.
However, Z3 uses many engines to process quantified formulas. The MBQI module can handle this quantified formula, and build satisfying assignments for problems such as:
(declare-sort S)
(declare-fun s () S)
(assert (forall ((t S)) (= t s)))
(declare-fun a () S)
(declare-fun b () S)
(assert (= a b))
(check-sat)
(model)
That being said, the quantified formula above is not the best way to specify a sort with a single element.
You can use datatypes to encode enumeration types.
For example, the following command defines a sort S with elements e1 … en.
(declare-datatypes ((S e1 e2 … en)))
A sort with only one element can be specified using:
(declare-datatypes ((S e)))
The following example is unsatisfiable:
(declare-datatypes ((S elem)))
(declare-const a S)
(declare-const b S)
(assert (not (= a b)))
(check-sat)

How do I map a macro across a list in Scheme?

I have a Scheme macro and a long list, and I'd like to map the macro across the list, just as if it were a function. How can I do that using R5RS?
The macro accepts several arguments:
(mac a b c d)
The list has
(define my-list ((a1 b1 c1 d1)
(a2 b2 c2 d2)
...
(an bn cn dn)))
And I'd like to have this:
(begin
(mac a1 b1 c1 d2)
(mac a2 b2 c2 d2)
...
(mac an bn cn dn))
(By the way, as you can see I'd like to splice the list of arguments too)
Expanding on z5h's answer of using eval, the methods below show how a map-macro macro can be written if interaction-environment in implemented in the version of R5RS in use:
(define test-list '((1 2 3 4)
(5 6 7 8)))
;Or if your version of scheme implments interaction-environment then:
(define-syntax trade
(syntax-rules ()
((_ a b c d) (display (list b a d c)))))
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;Careful this is not really mapping. More like combined map and apply.
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
(define-syntax map-macro
(syntax-rules ()
((_ mac ls) (let ((mac-list (map (lambda (lst) (cons 'trade lst)) ls)))
(eval
`(begin
,#mac-list)
(interaction-environment))))
))
(map-macro trade test-list)
;outputs: (2 1 4 3)(6 5 8 7)
So that last map-macro call evaluates the following:
What ends up getting evaluated from (map-macro trade test-list) is:
(begin
(trade 1 2 3 4)
(trade 5 6 7 8))
Which is not quite a map, but I believe it does answers your question.
Syntactic extensions are expanded into
core forms at the start of evaluation
(before compilation or interpretation)
by a syntax expander. -Dybvig, "The
Scheme Programming Language:
A macro operates on syntax. This happens before compilation or execution. It gives you another way of writing the same code.
A function operates on variables and values (which might be lists, atoms, numbers, etc) who's value is known when the function is invoked.
So mapping a macro doesn't make sense. You're asking to invoke something (macro expansion) that already happened long ago.
If you need something to write code for you and evaluate it at runtime, then might be one of those cases where you need eval.
Would something like
(map (lambda (l) (mac (car l) (caar l) (caaar l) (caaaar l))) mylist)
work?