Simplifying a group of AND and OR clauses - logic

So if I have a group of AND and OR clauses as follows:
Y = ( A + B ) . ( A + C' ) . ( B + D' )
Can I simplify it like this:
Y = A . ( B + C' ) . ( B + D' ) ; Because A is common to ( A + B ) and ( A + C' )
Y = A . B . ( C' + D' ) ; Because B is common to ( B + C' ) and ( B + D' )
Thanks for your time.

No, if you use the following values:
A = 1
B = 0
C = 0
D = 0
Then the original statement is true where your simplified version is false. You can find another way to represent it by expanding the boolean expression and then attempting to reduce it algebraicly, like this:
(A + B)(A + C')(B + D')
(AA + AC' + AB + BC')(B + D') // expand first 2 groups
AAB + ABC' + ABB + BBC' + AAD' + AC'D' + ABD' + BC'D' // expand all groups
AB + ABC' + AB + BC' + AD' + AC'D' + ABD' + BC'D' // apply identity to reduce
AB + BC' + AD' // eliminate redundant expressions
That final result would look like this in your notation
(A . B) + (B . C') + (A . D')
One step further could bring it to
B . (A + C') + (A . D')
or
A . (B + D') + (B . C')

The only equivalence I can think of as useful here is
(A+B).(A+C') === A+(B.C')
So it becomes
(A+(B.C')) . (B+D')
if B: --> A . D'
else: --> (A+C')
Don't know whether that helps you get anything more efficient/useful
A B C' D' f()
TRUE TRUE TRUE TRUE TRUE
TRUE TRUE TRUE FALSE TRUE
TRUE TRUE FALSE TRUE TRUE
TRUE TRUE FALSE FALSE TRUE
TRUE FALSE TRUE TRUE TRUE
TRUE FALSE TRUE FALSE TRUE
TRUE FALSE FALSE TRUE FALSE
TRUE FALSE FALSE FALSE FALSE
FALSE TRUE TRUE TRUE TRUE
FALSE TRUE TRUE FALSE FALSE
FALSE TRUE FALSE TRUE TRUE
FALSE TRUE FALSE FALSE FALSE
FALSE FALSE TRUE TRUE FALSE
FALSE FALSE TRUE FALSE FALSE
FALSE FALSE FALSE TRUE FALSE
FALSE FALSE FALSE FALSE FALSE
Watch it live in a spreadsheet: google docs

eZanmoto, at first glance it looks like it would work, but I quick went through and did truth tables for each one and here are the cases where it fails:
#A = B = C = D = True
Original = True
First = True
Second = False
#A = C = True, B = D = True
Original = True
First = False
Second = False
#A = True, B = C = D = False
Original = True
First = True
Second = False
#A = C = False, B = D = True
Original = True
First = False
Second = False
#A = C = D = False, B = True
Original = True
First = False
Second = False

Late answer. I recently learned more about Quine-McClusky algorithm and Karnaugh maps, which are systematic approaches to mimizing boolean epxressions.
I stumbled across this python implementation that seemed nice and thought I'd verify my earlier answer using it:
import logic
A,B,C,D = logic.bools('ABCD')
print logic.boolsimp((A & B) | (A & ~C) | (B & ~D))
Sure enough it prints
(B & ~D) | (~C & A) | (B & A)
Pythonists: nevermind the strange choice of operators for logical operations; this is mainly due to the fact that and, or and not cannot be overloaded in Python
Sanity check
As a sanity check I did check that the equivalence that I thought would lead to a potential simplification was 'seen' by the algorithm implementation:
print logic.boolsimp((A & B) | (A & ~C))
print logic.boolsimp(A & (B | ~C))
prints twice the same output ((~C & A) | (B & A))

Related

Two very close floating point numbers are not equal

In IRB:
0.9999999999999998 == 1.0
# => false
0.99999999999999998 == 1.0
# => true
Also just showing the inspect values:
0.9999999999999998
# => 0.9999999999999998
0.99999999999999998
# => 1.0
In my case the value created by my program is unfortunately the first one, so I'm having trouble writing a test case which validates the value as equal to one.
I am deciding between the following options:
add round calls in the application code, however the application is already working, I just am unable to test
add round calls in the testing code
???
What would be your recommended approach? Is there a way I can configure my program to treat 0 with fifteen nines after the decimal as equal to 1.0? It feels a bit frustrating because sixteen nines after the decimal seems to be the cut off - I'm only one short.
Reading this article on how to compare small floating-point differences:
http://c-faq.com/fp/fpequal.html
I converted their proposed solutions to Ruby:
class Float
MY_EPSILON = 0.000000000000001
MY_TOLERANCE = 0.000000000000001
def eq_epsilon?(flt)
a = self
b = flt
(a - b).abs <= MY_EPSILON * a.abs
end
def self.reldif(a, b)
c = a.abs
d = b.abs
d = [c,d].max
d == 0.0 ? 0.0 : (a - b).abs / d
end
def eq_reldif?(flt)
Float.reldif(self, flt) <= MY_TOLERANCE
end
end
And thus we can run some test code:
f1 = 0.99999999999999998
f2 = 0.9999999999999998
f3 = 0.999999999999998
[f1, f2, f3].each { |f|
p f.eq_epsilon?(1.0)
p 1.0.eq_epsilon?(f)
}
puts "--------------"
[f1, f2, f3].each { |f|
p f.eq_reldif?(1.0)
p 1.0.eq_reldif?(f)
}
With output:
true
true
true
true
false
false
--------------
true
true
true
true
false
false
However more testing is probably needed to make sure it satisfies all your requirements.

Why is head-tail pattern matching so much faster than indexing?

I was working on a HackerRank problem today and initially wrote it with indexing and it was incredibly slow for most of the test cases because they were huge. I then decided to switch it to head:tail pattern matching and it just zoomed. The difference was absolutely night and day, but I can't figure out how it was such a change in efficiency. Here is the code for reference if it is at all useful
Most efficient attempt with indexing
count :: Eq a => Integral b => a -> [a] -> b
count e [] = 0
count e (a:xs) = (count e xs +) $ if a == e then 1 else 0
fullCheck :: String -> Bool
fullCheck a = prefixCheck 0 (0,0,0,0) a (length a) && (count 'R' a == count 'G' a) && (count 'Y' a == count 'B' a)
prefixCheck :: Int -> (Int, Int, Int, Int) -> String -> Int -> Bool
prefixCheck n (r',g',y',b') s l
| n == l = True
| otherwise =
((<= 1) $ abs $ r - g) && ((<= 1) $ abs $ y - b)
&& prefixCheck (n+1) (r,g,y,b) s l
where c = s !! n
r = if c == 'R' then r' + 1 else r'
g = if c == 'G' then g' + 1 else g'
y = if c == 'Y' then y' + 1 else y'
b = if c == 'B' then b' + 1 else b'
run :: Int -> IO ()
run 0 = putStr ""
run n = do
a <- getLine
print $ fullCheck a
run $ n - 1
main :: IO ()
main = do
b <- getLine
run $ read b
head:tail pattern matching attempt
count :: Eq a => Integral b => a -> [a] -> b
count e [] = 0
count e (a:xs) = (count e xs +) $ if a == e then 1 else 0
fullCheck :: String -> Bool
fullCheck a = prefixCheck (0,0,0,0) a && (count 'R' a == count 'G' a) && (count 'Y' a == count 'B' a)
prefixCheck :: (Int, Int, Int, Int) -> String -> Bool
prefixCheck (r,g,y,b) [] = r == g && y == b
prefixCheck (r',g',y',b') (h:s) = ((<= 1) $ abs $ r - g) && ((<= 1) $ abs $ y - b)
&& prefixCheck (r,g,y,b) s
where r = if h == 'R' then r' + 1 else r'
g = if h == 'G' then g' + 1 else g'
y = if h == 'Y' then y' + 1 else y'
b = if h == 'B' then b' + 1 else b'
run :: Int -> IO ()
run 0 = putStr ""
run n = do
a <- getLine
print $ fullCheck a
run $ n - 1
main :: IO ()
main = do
b <- getLine
run $ read b
For reference as well, the question was
You are given a sequence of N balls in 4 colors: red, green, yellow and blue. The sequence is full of colors if and only if all of the following conditions are true:
There are as many red balls as green balls.
There are as many yellow balls as blue balls.
Difference between the number of red balls and green balls in every prefix of the sequence is at most 1.
Difference between the number of yellow balls and blue balls in every prefix of the sequence is at most 1.
Where a prefix of a string is any substring from the beginning to m where m is less than the size of the string
You have already got the answer in the comments why lists indexing performs linearly. But, if you are interested in a more Haskell style solution to the Hackerrank problem your referring to, even head-tail pattern matching is unnecessary. A more performant solution can be done with right folds:
import Control.Applicative ((<$>))
import Control.Monad (replicateM_)
solve :: String -> Bool
solve s = foldr go (\r g y b -> r == g && y == b) s 0 0 0 0
where
go x run r g y b
| 1 < abs (r - g) || 1 < abs (y - b) = False
| x == 'R' = run (r + 1) g y b
| x == 'G' = run r (g + 1) y b
| x == 'Y' = run r g (y + 1) b
| x == 'B' = run r g y (b + 1)
main :: IO ()
main = do
n <- read <$> getLine
replicateM_ n $ getLine >>= print . solve

How do I implement a brushfire algorithm in Lua?

I am working on implementing "Goal-based vector field pathfinding" (demonstrated in the article at this link) It requires that I label every node in my world graph with a path distance from the goal node and recommends using a brushfire (wavefront) algorithm to do this. This is the area I am having issues in. When I get to the 8th iteration of my while loop and the 6th iteration of my nested for, I get a nil reference error on the marked line.
g is my graph, which has an 8-way adjacency list form.
q is an instance of this FIFO lua library.
rtx and rty are the x and y coords of the root node.
d is an iterator added to keep track of the path distance assigned to each node.
The structure of each node in the graph is not the same as the structure of a node being processed.
Node for processing:
n = {}
n[1] = x coord
n[2] = y coord
n[3] = adjacency list (eight entries)
n.vX = x componant of vector for vector field
n.vY = y componant of vector for vector field
Node stored in graph:
n = {}
n[1] = adjacency list
n.vX = x componant of vector for vector field
n.vY = y componant of vector for vector field
Beneath is my implementation so far. The t in the for loop is just a temporary node used to pass information along to the queue. BTW t is where the distance of all the nodes gets set.
local function brushFire( g, rtx, rty )
local q = q.new()
local s = {}
s[1] = rtx
s[2] = rty
s[3] = g[rtx][rty][3]
s.dist = 0
q:pushRight( s )
s = nil
local d = 0
while( table.getn( q.list[q.first] ) ~= 0 ) do
print( d )
local n = q:popLeft()
setDist( g, n )
print( #n[3] )
for i = 1, #n[3] do
print( ":"..i )
if( g[n[3][i][4]][n[3][i][2]].v ~= true ) then
g[n[3][i][5]][n[3][i][2]].v = true
local t = {}
t[1] = n[3][i][1]
t[2] = n[3][i][2]
t[3] = g[n[3][i][7]][n[3][i][2]][1] <------Error here
t.dist = d
q:pushRight( t )
t = nil
end
end
d = d + 1
end
end
Let me know if you need more information in order to answer my question.
I found the answer to my problem. If anyone wants to use the source, I am posting it below:
Queue module:
local q = {}
local q_mt = { __index = q }
function q.new()
local nq = { first = 0, last = -1, list = {} }
return setmetatable( nq, q_mt )
end
function q:pushLeft( value )
local first = self.first - 1
self.first = first
self.list[first] = value
end
function q:pushRight( value )
local last = self.last + 1
self.last = last
self.list[last] = value
end
function q:popLeft()
local first = self.first
if first > self.last then error( "list is empty" ) end
local value = self.list[first]
self.list[first] = nil
self.first = first + 1
return value
end
function q:popRight()
local last = self.last
if self.first > last then error( "list is empty" ) end
local value = self.list[last]
self.list[last] = nil
self.last = last - 1
return value
end
return q
The following module creates a vector field which points towards a goal when pathFind.findPath is called:
local q = require( "Queue" )
local pathFind = {}
local pathFind_mt = { __index = pathFind }
-- Private Functions
local function genDistMap( g, rtx, rty ) -<-<-<- genDistMap is the brushfire part
local q = q.new()
local g = g
g[rtx][rty].v = true
g[rtx][rty].dist = 0
local s = {}
s[1] = rtx
s[2] = rty
s[3] = g[rtx][rty][1]
s.dist = 0
q:pushRight( s )
s = nil
while( q.list[q.first] ~= nil ) do
local n = q:popLeft()
for i = 1, #n[3] do
local x, y = n[3][i][1], n[3][i][2]
if( g[x][y].v ~= true ) then
g[x][y].v = true
local t = {}
t[1] = x
t[2] = y
t[3] = g[x][y][1]
t.dist = n.dist + 1
g[x][y].dist = n.dist + 1
q:pushRight( t )
t = nil
end
end
end
return g
end
local function genVectorField( nodes )
local nodes = nodes
for i = 2, #nodes - 1 do
for j = 2, #nodes[i] - 1 do
local a = nodes[i - 1][j].dist - nodes[i + 1][j].dist
local b = nodes[i][j - 1].dist - nodes[i][j + 1].dist
local c = math.sqrt( a*a + b*b )
nodes[i][j].vX = a/c*5
nodes[i][j].vY = b/c*5
end
end
return nodes
end
-- Public Functions
function pathFind.new()
local newPathFind = {}
return setmetatable ( newPathFind, pathFind_mt )
end
function pathFind.findPath( nodeSet, rootX, rootY )
local nodes = nodeSet
nodes = genDistMap( nodes, rootX, rootY )
nodes = genVectorField( nodes )
return( nodes )
end
return pathFind

Convert function from string to nat in Coq

I would like to write a function convert type string -> nat in coq.
Where the string contents only number will return nat otherwise it will return 0 for the alphabet or alphabet with number or any cases that is not contain number (for example: ', -, ...).
For example:
"0", "1", "2", "3", ... "99",.. will return : 0, 1, 2, 3, ..., 99, ...
"a", "bc", "..0d",... will return : 0
Am I able to write this function in Coq?
I tried by myself but I do not know how can I convert just the number and not the alphabet like my example?
Require Import Ascii String.
Definition nat_of_string (s : string) : nat :=
match s with
| EmptyString => 0
| String (s) _ => nat_of_ascii s
end.
Here is my really inefficient version (for clarity):
Require Import String Ascii.
Open Scope string_scope.
ascii in Coq is a 8-bit representation of ascii characters, so you can pattern match to only translate 0 to 9, the rest is sent to None
Definition num_of_ascii (c: ascii) : option nat :=
match c with
(* Zero is 0011 0000 *)
| Ascii false false false false true true false false => Some 0
(* One is 0011 0001 *)
| Ascii true false false false true true false false => Some 1
(* Two is 0011 0010 *)
| Ascii false true false false true true false false => Some 2
| Ascii true true false false true true false false => Some 3
| Ascii false false true false true true false false => Some 4
| Ascii true false true false true true false false => Some 5
| Ascii false true true false true true false false => Some 6
| Ascii true true true false true true false false => Some 7
| Ascii false false false true true true false false => Some 8
| Ascii true false false true true true false false => Some 9
| _ => None
end.
To compute 123 from "123", I find it easier to parse the string in reverse order:
12345 = 5 + 10 * (4 + 10 * (3 + 10 * (2 + 10 * 1)))
(* Inefficient string reversal *)
Fixpoint string_rev (s : string) : string :=
match s with
| EmptyString => EmptyString
| String c rest => append (string_rev rest) (String c EmptyString)
end.
Fixpoint num_of_string_rec (s : string) : option nat :=
match s with
| EmptyString => Some 0
| String c rest =>
match (num_of_ascii c), (num_of_string_rec rest) with
| Some n, Some m => Some (n + 10 * m)
| _ , _ => None
end
end.
Definition num_of_string (s : string) :=
match num_of_string_rec (string_rev s) with
| Some n => n
| None => 0
end.
Eval vm_compute in num_of_string "789".
In the end, you have what you want. Be careful not to try with huge numbers, it might take a while, but you get the idea!
Best, V.
The previous answer is nice but a bit boring to write and read, and because it uses natural numbers,
it is very limited. Why not move directly to integers?
First map every ascii character to an integer:
Require Import ZArith String Ascii.
Open Scope Z_scope.
Definition Z_of_bool (b : bool) := if b then 1 else 0.
(* This coercion is used to make the next function shorter to write and read *)
Coercion Z_of_bool : bool >-> Z.
Definition Z_of_ascii a :=
match a with
Ascii b1 b2 b3 b4 b5 b6 b7 b8 =>
b1 + 2 * (b2 + 2 * (b3 + 2 * (b4 + 2 *
(b5 + 2 * (b6 + 2 * (b7 + 2 * b8))))))
end.
Only one case needs to be done, and the digits are neatly placed one after the other in the order you obtain (the ascii code was designed that way, long before Coq was invented).
Definition Z_of_0 := Eval compute in Z_of_ascii "0".
Definition Z_of_digit a :=
let v := Z_of_ascii a - Z_of_0 in
match v ?= 0 with
Lt => None | Eq => Some v |
Gt => match v ?= 10 with Lt => Some v | _ => None end
end.
Here is another attempt at handling strings with several digits, without reversing the list.
Fixpoint num_prefix_and_length (s : string) : option (Z * Z) :=
match s with
EmptyString => None
| String a s' =>
match Z_of_digit a with
None => None
| Some va =>
match num_prefix_and_length s' with
None => Some (va, 1)
| Some (vs, n) => Some (va * 10 ^ n + vs, n+1)
end
end
end.
In this case, the function accepts strings that have any trailing characters.
Compute num_prefix_and_length "31415926 remind me of Pi".
returns Some (31415926, 8).

Optimizing the damerau version of the levenshtein algorithm to better than O(n*m)

Here is the algorithm (in ruby)
#http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
def self.dameraulevenshtein(seq1, seq2)
oneago = nil
thisrow = (1..seq2.size).to_a + [0]
seq1.size.times do |x|
twoago, oneago, thisrow = oneago, thisrow, [0] * seq2.size + [x + 1]
seq2.size.times do |y|
delcost = oneago[y] + 1
addcost = thisrow[y - 1] + 1
subcost = oneago[y - 1] + ((seq1[x] != seq2[y]) ? 1 : 0)
thisrow[y] = [delcost, addcost, subcost].min
if (x > 0 and y > 0 and seq1[x] == seq2[y-1] and seq1[x-1] == seq2[y] and seq1[x] != seq2[y])
thisrow[y] = [thisrow[y], twoago[y-2] + 1].min
end
end
end
return thisrow[seq2.size - 1]
end
My problem is that with a seq1 of length 780, and seq2 of length 7238, this takes about 25 seconds to run on an i7 laptop. Ideally, I'd like to get this reduced to about a second, since it's running as part of a webapp.
I found that there is a way to optimize the vanilla levenshtein distance such that the runtime drops from O(n*m) to O(n + d^2) where n is the length of the longer string, and d is the edit distance. So, my question becomes, can the same optimization be applied to the damerau version I have (above)?
Yes the optimization can be applied to the damereau version. Here is a haskell code to do this (I don't know Ruby):
distd :: Eq a => [a] -> [a] -> Int
distd a b
= last (if lab == 0 then mainDiag
else if lab > 0 then lowers !! (lab - 1)
else{- < 0 -} uppers !! (-1 - lab))
where mainDiag = oneDiag a b (head uppers) (-1 : head lowers)
uppers = eachDiag a b (mainDiag : uppers) -- upper diagonals
lowers = eachDiag b a (mainDiag : lowers) -- lower diagonals
eachDiag a [] diags = []
eachDiag a (bch:bs) (lastDiag:diags) = oneDiag a bs nextDiag lastDiag : eachDiag a bs diags
where nextDiag = head (tail diags)
oneDiag a b diagAbove diagBelow = thisdiag
where doDiag [_] b nw n w = []
doDiag a [_] nw n w = []
doDiag (apr:ach:as) (bpr:bch:bs) nw n w = me : (doDiag (ach:as) (bch:bs) me (tail n) (tail w))
where me = if ach == bch then nw else if ach == bpr && bch == apr then nw else 1 + min3 (head w) nw (head n)
firstelt = 1 + head diagBelow
thisdiag = firstelt : doDiag a b firstelt diagAbove (tail diagBelow)
lab = length a - length b
min3 x y z = if x < y then x else min y z
distance :: [Char] -> [Char] -> Int
distance a b = distd ('0':a) ('0':b)
The code above is an adaptation of this code.

Resources