Exclusion and inclusion in Z3 - set

I am trying to model inclusion and exclusion of elements in sets with Z3. In particular inclusion of elements with distinct values, and exclusion of elements not already in a target set. So basically I want to have a set U and have Z3 find a set U_d that only contains elements of U with distinct values.
My current approach uses quantifiers, but I'm having trouble understanding how to state that I want to always include elements in U_d if they appear in U.
( set-option :produce-models true)
;;; Two simple sorts.
;;; Sets and Zs.
( declare-sort Z 0 )
( declare-sort Set 0 )
;;; A set can contain a Z or not.
;;; Zs can have a value.
( declare-fun contains (Set Z) bool )
( declare-fun value (Z) Int )
;;; Two sets and two Z instances for use in the example.
( declare-const set Set )
( declare-const distinct_set Set )
( declare-const A Z )
( declare-const B Z )
;;; The elements and sets are distinct.
( assert ( distinct A B ) )
( assert ( distinct set distinct_set ) )
;;; Set 'set' contains A but not B
( assert ( = ( contains set A ) true ) )
( assert ( = ( contains set B ) false ) )
;;; Assert that all elements contained by distinct_set have different values unless they're the same variable.
( assert
( forall ( (x Z) (y Z) )
( =>
( and
( contains distinct_set x )
( contains distinct_set y )
( = ( value x ) ( value y ) ) )
( = x y ) )))
;;; distinct_set can contain only elements that appear in set.
;;; In other words, distinct_set is a proper set.
( assert
( forall ( ( x Z ) )
( =>
( contains distinct_set x )
( contains set x ))))
;;; Give elements some values.
( assert ( = (value A) 0 ) )
( assert ( = (value B) 1 ) )
( push )
( check-sat )
( get-value (( contains distinct_set A )))
( get-value (( contains distinct_set B )))
( pop )
The assignments it produces are:
sat
((( contains distinct_set A ) false))
((( contains distinct_set B ) false))
The assignments I would like are:
sat
((( contains distinct_set A ) true))
((( contains distinct_set B ) false))
I understand that an assignment of false to both A and B is a logically correct assignment, but I don't know how to state things in such a way as to rule those sorts of cases out.
Perhaps I'm not thinking about the problem correctly.
Any advice would be much appreciated. :)

What do you think of the following assertion?
(assert
(forall ((x Z))
(=> (contains set x)
(exists ((y Z))
(and (= (value x) (value y))
(contains set y)
(contains distinct_set y))))))
It says that for every element x of set (i.e., U), there is a y s.t.
value of y is equal to value of x
y is also an element of set
y is an element of distinct_set (i.e., U_d)
This assertion makes sure that if there are two elements in set with the same value, then one and only one of them is an element of distinct_set. Is that what you want?
Note that, if we just add this assertion, Z3 will still produce a model where
((( contains distinct_set A ) false))
((( contains distinct_set B ) false))
If we inspect the model produced by Z3 using (get-model), we will notice that set contains another element different from A. So, to force set to contain only the element A, we have to assert
(assert
(forall ((x Z))
(= (contains set x) (= x A))))
After you add this assertion, the following two assertions become redundant:
( assert ( = ( contains set A ) true ) )
( assert ( = ( contains set B ) false ) )
Now, let us consider the case where set contains two values: A and C, and they both have the same value. The following script also asks questions such as: is there a model where
distinct_set does not contain A
distinct_set does not contain A nor C
distinct_set contains A and C
Script:
( set-option :produce-models true)
;;; Two simple sorts.
;;; Sets and Zs.
( declare-sort Z 0 )
( declare-sort Set 0 )
;;; A set can contain a Z or not.
;;; Zs can have a value.
( declare-fun contains (Set Z) bool )
( declare-fun value (Z) Int )
;;; Two sets and two Z instances for use in the example.
( declare-const set Set )
( declare-const distinct_set Set )
( declare-const A Z )
( declare-const B Z )
( declare-const C Z )
;;; The elements and sets are distinct.
( assert ( distinct A B C) )
( assert ( distinct set distinct_set ) )
;;; set contains only A and C
(assert
(forall ((x Z))
(= (contains set x) (or (= x A) (= x C)))))
;;; Assert that all elements contained by distinct_set have different values unless they're the same variable.
( assert
( forall ( (x Z) (y Z) )
( =>
( and
( contains distinct_set x )
( contains distinct_set y )
( = ( value x ) ( value y ) ) )
( = x y ) )))
;;; distinct_set can contain only elements that appear in set.
;;; In other words, distinct_set is a proper set.
( assert
( forall ( ( x Z ) )
( =>
( contains distinct_set x )
( contains set x ))))
;;; Give elements some values.
( assert ( = (value A) 0 ) )
( assert ( = (value B) 1 ) )
( assert ( = (value C) 0 ) )
(assert
(forall ((x Z))
(=> (contains set x)
(exists ((y Z))
(and (= (value x) (value y))
(contains set y)
(contains distinct_set y))))))
( push )
( check-sat )
( get-model )
( get-value (( contains distinct_set A )))
( get-value (( contains distinct_set B )))
( get-value (( contains distinct_set C )))
( echo "Is there another model where A is not in distinct_set")
( assert (not ( contains distinct_set A )))
(check-sat)
( get-value (( contains distinct_set A )))
( get-value (( contains distinct_set B )))
( get-value (( contains distinct_set C )))
( echo "Is there another model where A and C are not in distinct_set")
( assert (not ( contains distinct_set C )))
(check-sat)
( pop ) ;; retracting the last two assertions
( push )
( echo "Is there a model where A and C are in distinct_set")
( assert ( contains distinct_set A ))
( assert ( contains distinct_set C ))
( check-sat )

Related

Candidate elimination algorithm lecture example

I am looking through some lecture slides and cannot understand why the bold hypothesis at last G are just discarded, I can come to the same answer but don't understand why they're just discarded.
sky temperature humidity
| | | | | |
Sunny Rainy Warm Coo Normal Low
and the set of positive and negative training examples:
1. ( S W N )+)
2. ( R C L )-)
3 . ( S C N )+)
4. ( S W L )-)
Training with the first example: ( S W N ) +) generalizing…
G = [( ? ? ? )]
S = [( S W N )]
Training with the second example: ( R C L ) -) specializing…
G = [( S ? ? ) ( ? W ? ) ( ? ? N )
S = [( S W N )]
Training with the third example: ( S C N ) +) generalizing…
G = [( S ? ? )( ? ? N )] (the other is discarded )
S = [( S ? N )]
Training with the fourth example: ( S W L ) -) specializing…
G = [( S C ? )( S ? N )( R ? N )(? C N)] (bold are discarded )
S = [( S ? N )]
Convergence, the learned concept must be: [( S ? N )]
G = [( S C ? )( S ? N )( R ? N )(? C N)] (bold are discarded )
It can be simply using the candidate elimination algorithm. According to that the reasons can be summarized as follows.
Inconsistent hypothesis: According to the algorithm we have to first remove the hypotheses which are not consistent with target data(D)
In this case ( R ? N ) is removed it's inconsistent with ( S ? N )
Specific boundary being more general than the general boundary.
If the specific boundy become more specific that the general one. There can be a boundary overlapping.
if we compare derived ( S C ? ) with ( S ? N ) , we can compare middle c with ? of (S ? N). The derived one having a constant makes it more specific compared to the specific boundary. So it should be removed. Same goes with (? C N).
I see the question is bit older but I hope someone would find this useful.

First order logic resolution algorithm . Ask with a negative request

I try to ask a knowledge base with a negative request. So before the resolution the complement (positif here) is add to the set of clauses uses by the algorithm.
With these facts:
Spouse(Sarah,Andrew)
Spouse(Sophie,Edward)
And theses axioms :
(∀ [a , b , c ] ( ( ( Spouse(a,c) ∧ Spouse(b,c) ) ⇒ Egal(a,b) ) ))
this axiom mean onely two people can be spouse
(∀ [a , b ] ( ( Spouse(a,b) ⇔ Spouse(b,a) ) ))
(∀ [x ] ( Egal(x,x) ))
(∀ [x , y ] ( ( Egal(x,y) ⇒ Egal(y,x) ) ))
reverse
(∀ [x , y , z ] ( ( ( Egal(x,y) ∧ Egal(y,z) ) ⇒ Egal(x,z) ) ))
transitive
(∀ [x ] ( ( Egal(x,x) ⇒ Egal(x,x) ) ))
clauses turn into CNF
( ( ¬ Spouse(a0,c0) ∨ ¬ Spouse(b0,c0) ) ∨ Egal(a0,b0) )
( ¬ Spouse(a1,b1) ∨ Spouse(b1,a1) )
( ¬ Spouse(b2,a2) ∨ Spouse(a2,b2) )
Egal(x0,x0)
( ¬ Egal(x1,y0) ∨ Egal(y0,x1) )
( ( ¬ Egal(x2,y1) ∨ ¬ Egal(y1,z0) ) ∨ Egal(x2,z0) )
( ¬ Egal(x3,x3) ∨ Egal(x3,x3) )
I can request
Spouse(Sarah,Andrew) or Spouse(Sophie,Edward)
this request ¬Spouse(Sarah,Edward) : is Sarah not spouse with Edward, doesn't work.
Of course I can ask if Spouse(Sarah,Edward) : is Sarah spouse with Edward, get no answer et consider that it's false.
What's wrong with this kind of request, because I don't know if there is a bug into my implementation or if it is not possible to do that (it's suppose to ...).
Thanks for your help !

batch if not exist takes out drive letter from variable

Batch File:
#echo off
echo.
echo Verifying existence of File
for %%d in (c d e f g h i j k l m n o p q r s t u v w x y z) do (
if exist %%d:\dir1\dir2\dir3\file1 (
set BDCPATH=%%d:\dir1\dir2\dir3\file1
) else if exist %%d:\dir1_2\dir2\dir3\file1 (
set BDCPATH=%%d:\dir1_2\dir2\dir3\file1
)
)
echo %BDCPATH%
echo %BDCPATH%
IF NOT EXIST %BCDPATH% echo %BCDPATH%
goto :eof
When I echo the '%BDCPATH% variable, it takes out the drive letter. Can you explain why this happens and a fix for this?
cmd output:
c:\Tools\KDNET_Helper>C:\Users\c_jamesp\Desktop\test1.bat
Verifying existence of BCD File
i:\dir1\dir2\dir3\file1
i:\dir1\dir2\dir3\file1
dir1\dir2\dir3\file1
Try this: the quotes fix an issue with certain path names, and the parentheses are changed.
Note that if neither of those path\file exists then the variable will not be set.
#echo off
echo.
echo Verifying existence of File
set "bcdpath="
for %%d in (c d e f g h i j k l m n o p q r s t u v w x y z) do (
if exist "%%d:\dir1\dir2\dir3\file1" (
set "BDCPATH=%%d:\dir1\dir2\dir3\file1"
) else (
if exist "%%d:\dir1_2\dir2\dir3\file1" set "BDCPATH=%%d:\dir1_2\dir2\dir3\file1"
)
)
echo "%BDCPATH%"
echo "%BDCPATH%"
IF NOT EXIST "%BCDPATH%" echo "%BCDPATH%"
if not defined bcdpath echo no files found
pause
goto :eof
good guess, but by spending more time playing around I found out two things:
#echo off
echo.
echo Verifying existence of File
for %%d in (c d e f g h i j k l m n o p q r s t u v w x y z) do (
if exist %%d:\dir1\dir2\dir3\file1 (
set BDCPATH=%%d:\dir1\dir2\dir3\file1
) else if exist %%d:\dir1_2\dir2\dir3\file1 (
set BDCPATH=%%d:\dir1_2\dir2\dir3\file1
)
)
echo %BDCPATH%
echo %BDCPATH%
IF NOT EXIST %BDCPATH% echo %BDCPATH%
:eof
I had %BCDPATH% instead of %BDCPATH%
It should just be either goto somename and not goto :somename.

SPOJ Problem Flibonakki time limit exceed

I am trying to solve this problem in Haskell but getting time limit exceed. I applied all my Haskell and mathematical skill to optimize this but all in vain. Could some one please suggest me how to optimize this code further. The sequence F_3 + F_7 + F_11 .... + F_(4n+3) = F_2n*F_(2n+1). I used O(log n) to method to calculate the Fibonacci numbers.
import Data.List
import Data.Maybe
import qualified Data.ByteString.Lazy.Char8 as BS
matmul :: [Integer] -> [Integer] -> Integer -> [Integer]
matmul [a,b,c] [d,e,f] m = [x,y,z] where
y = (a*e + b*f) `mod` m
z = (b*e + c*f) `mod` m
x = y + z
powM ::[Integer] -> Integer -> Integer -> [Integer]
powM a n m | n == 1 = a
| n == 2 = matmul a a m
| even n = powM ( matmul a a m ) ( div n 2 ) m
| otherwise = matmul a ( powM ( matmul a a m ) ( div n 2 ) m ) m
readInt :: BS.ByteString -> Integer
readInt = fst.fromJust.BS.readInteger
solve::Integer -> BS.ByteString
solve n = BS.pack.show $ mod ( c*d ) 1000000007 where
[c,d,_] = powM [1,1,0] ( 2*n ) 1000000007
--([_,a,_]:_) = powM [[1,2,1],[0,5,3],[0,3,2]] n 1000000007
-- f_3+f_7+f_11+f_15 = f_2n*f_(2n+1)
main = BS.interact $ BS.unlines. map ( solve.readInt ) . tail . BS.lines
Your solving seems to be fast enough but it seems that your main function does not print the answer after each new line. In fact it requires an extra newline to get the last answer so this can be the cause of your timeout! Here is a version that prints each answer directly after the input.
import Data.List
import Data.Maybe
import Control.Monad
import qualified Data.ByteString.Lazy.Char8 as B
import qualified Data.ByteString.Char8 as BC
import qualified Text.Show.ByteString as BS
matmul :: [Integer] -> [Integer] -> Integer -> [Integer]
matmul [a,b,c] [d,e,f] m = [x,y,z] where
y = (a*e + b*f) `mod` m
z = (b*e + c*f) `mod` m
x = y + z
powM :: [Integer] -> Integer -> Integer -> [Integer]
powM a n m | n == 1 = a
| n == 2 = matmul a a m
| even n = powM ( matmul a a m ) ( div n 2 ) m
| otherwise = matmul a ( powM ( matmul a a m ) ( div n 2 ) m ) m
solve :: Integer -> Integer
solve n = mod ( c*d ) 1000000007
where
[c,d,_] = powM [1,1,0] ( 2*n ) 1000000007
readInteger :: B.ByteString -> Integer
readInteger = fst . fromJust . B.readInteger
readInt :: B.ByteString -> Int
readInt = fst . fromJust . B.readInt
get :: IO B.ByteString
get = liftM (B.fromChunks . (:[])) BC.getLine
main :: IO ()
main = do
n <- liftM readInt get
replicateM_ n ( liftM readInteger get >>= B.putStrLn . BS.show . solve )

Produce a sentence from a grammar with a given number of terminals

Say you've got a toy grammar, like: (updated so the output looks more natural)
S -> ${NP} ${VP} | ${S} and ${S} | ${S}, after which ${S}
NP -> the ${N} | the ${A} ${N} | the ${A} ${A} ${N}
VP -> ${V} ${NP}
N -> dog | fish | bird | wizard
V -> kicks | meets | marries
A -> red | striped | spotted
e.g., "the dog kicks the red wizard", "the bird meets the spotted fish or the wizard marries the striped dog"
How can you produce a sentence from this grammar according to the constraint that it must contain a total of n Vs + As + Ns. Given an integer the sentence must contain that many terminals. (note of course in this grammar the minimum possible n is 3).
The following Python code will generate a random sentence with the given number of terminals.
It works by counting the number of ways to produce a sentence of a given length, generating a large random number, and computing the indicated sentence.
The count is done recursively, with memoization.
An empty right hand side produces 1 sentence if n is 0 and 0 sentences otherwise.
To count the number of sentences produced by a nonempty right hand side, sum over i, the number of terminals used by the first symbol in the right hand side.
For each i, multiply the number of possibilities for the rest of the right hand side by the number of possibilities for the first symbol.
If the first symbol is a terminal, there is 1 possibility if i is 1 and 0 otherwise.
If the first symbol is a nonterminal, sum the possibilities over each alternative.
To avoid infinite loops, we have to be careful to prune the recursive calls when a quantity is 0.
This may still loop infinitely if the grammar has infinitely many derivations of one sentence.
For example, in the grammar
S -> S S
S ->
there are infinitely many derivations of the empty sentence: S => , S => S S => , S => S S => S S S => , etc.
The code to find a particular sentence is a straightforward modification of the code to count them.
This code is reasonably efficient, generating 100 sentences with 100 terminals each in less than a second.
import collections
import random
class Grammar:
def __init__(self):
self.prods = collections.defaultdict(list)
self.numsent = {}
self.weight = {}
def prod(self, lhs, *rhs):
self.prods[lhs].append(rhs)
self.numsent.clear()
def countsent(self, rhs, n):
if n < 0:
return 0
elif not rhs:
return 1 if n == 0 else 0
args = (rhs, n)
if args not in self.numsent:
sym = rhs[0]
rest = rhs[1:]
total = 0
if sym in self.prods:
for i in xrange(1, n + 1):
numrest = self.countsent(rest, n - i)
if numrest > 0:
for rhs1 in self.prods[sym]:
total += self.countsent(rhs1, i) * numrest
else:
total += self.countsent(rest, n - self.weight.get(sym, 1))
self.numsent[args] = total
return self.numsent[args]
def getsent(self, rhs, n, j):
assert 0 <= j < self.countsent(rhs, n)
if not rhs:
return ()
sym = rhs[0]
rest = rhs[1:]
if sym in self.prods:
for i in xrange(1, n + 1):
numrest = self.countsent(rest, n - i)
if numrest > 0:
for rhs1 in self.prods[sym]:
dj = self.countsent(rhs1, i) * numrest
if dj > j:
j1, j2 = divmod(j, numrest)
return self.getsent(rhs1, i, j1) + self.getsent(rest, n - i, j2)
j -= dj
assert False
else:
return (sym,) + self.getsent(rest, n - self.weight.get(sym, 1), j)
def randsent(self, sym, n):
return self.getsent((sym,), n, random.randrange(self.countsent((sym,), n)))
if __name__ == '__main__':
g = Grammar()
g.prod('S', 'NP', 'VP')
g.prod('S', 'S', 'and', 'S')
g.prod('S', 'S', 'after', 'which', 'S')
g.prod('NP', 'the', 'N')
g.prod('NP', 'the', 'A', 'N')
g.prod('NP', 'the', 'A', 'A', 'N')
g.prod('VP', 'V', 'NP')
g.prod('N', 'dog')
g.prod('N', 'fish')
g.prod('N', 'bird')
g.prod('N', 'wizard')
g.prod('V', 'kicks')
g.prod('V', 'meets')
g.prod('V', 'marries')
g.prod('A', 'red')
g.prod('A', 'striped')
g.prod('A', 'spotted')
g.weight.update({'and': 0, 'after': 0, 'which': 0, 'the': 0})
for i in xrange(100):
print ' '.join(g.randsent('S', 3))
Perhaps not the best solution, but I'd recursively work my way through each rule of the grammar until I've exceeded the constraint, then pop back and explore another path along the grammar. Keep all the sentences that meet the constraint and throw out all the sentences that don't.
For example, with n = 3:
S -> (${NP} ${VP}) -> ( (the ${N}) ${VP}) -> ( (the (dog) ${VP}) -> ... -> ( (the (dog) ( (kicks) (the ${NP} ) ) ) ) -> ( (the (dog) ( (kicks) (the (dog) ) ) ) )
And then pop back
( (the (dog) ( (kicks) (the ${N} ) ) ) ) -> ( (the (dog) ( (kicks) (the (fish) ) ) ) )
and a little while later...
( (the (dog) ( ${V} ${N} ) ) ) -> ( (the (dog) ( (meets) ${N} ) ) ) -> ( (the (dog) ( (meets) the (dog) ) ) )
etc.
Essentially a depth-first graph search, only you are building the graph as you are searching it (and you stop building parts that exceed the constraints).
This question contains a category error. The grammar you've specified has the appearance of a context free grammar, but the requirement that there be a specific number of terminal nodes requires a recursively enumerable grammar.

Resources