Convert function from string to nat in Coq - ascii

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).

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.

Flipping bits without getting negative number

How can I flip the bits of an integer without changing its sign? For example, how can I flip "1010" (1010) to "0101" (510)?
Bitwise negative operator results in negative number: ~10 (~0b1010) → -11 (0b0101).
You can flip the bits via XOR:
1010 (decimal 10)
XOR 1111 (decimal 15)
= 0101 (decimal 5)
In Ruby:
0b1010 ^ 0b1111 #=> 5
The number of 1's corresponds to the number of bits, therefore you could use:
num = 0b1010
num ^ (1 << num.bit_length) - 1
#=> 5
If you mean strings, then:
"1010".tr("01", "10") # => "0101"
If you mean numbers, then:
10.to_s(2).tr("01", "10").to_i(2) # => 5
I am not sure if it fits for your needs, but you can just flip binary string char by char like this:
"1010".chars.map { |i| i == "1" ? "0" : "1" }.join #=> "0101"
Upd:
How about this:
a = ~10
(a.bit_length - 1).downto(0).map { |i| a[i] }.join #=> "0101"

Solving a Programming Challenge: Apparatus, from Kattis

I am trying to solve apparatus problem described here. And I have a solution but it takes longer than 2 seconds which the time limit. I've tried to optimize my code for speed but can't get it with in the 2 second limit.
import sys
import math
for line in sys.stdin:
line = line.strip("\n").split(" ")
numSwitches = int(line[0])
numPics = int(line[1])
wiring = {}
inValid = False
for i in range(numPics):
if (inValid):
break
x = sys.stdin.readline().strip("\n")
f_x = sys.stdin.readline().strip("\n")
x_ones = 0
f_x_ones = 0
digit = 0
for i in range(numSwitches):
if f_x[i]=='1':
digit += 2**(numSwitches-i-1)
f_x_ones += 1
for switch in range(numSwitches):
if (x[switch]=='1'):
x_ones += 1
if not (switch in wiring.keys()):
wiring[switch] = digit
else:
wiring[switch] &= digit
if x_ones != f_x_ones:
inValid = True
break
if not inValid:
for i in wiring.values():
if i==0:
inValid = True
break
for possibilities in set(wiring.values()):
frequency = wiring.values().count(possibilities)
if frequency>1:
oneBits = 0
while (possibilities>0):
oneBits += (possibilities%2==1)
possibilities /= 2
if oneBits < frequency:
inValid = True
break
if not inValid:
print math.factorial(numSwitches-numPics)%1000003
else:
print 0
I'm looking for suggestions of ways I should have approached the problem or input on how I can optimize my current code.
Note:
Consider the following test case:
3 2
110
011
011
011
My code finds that is invalid in the following manner. First, upon encountering the first photograph (110, 011). The wiring dictionary gets assigned the following keys and values:
wiring[0] = 011
wiring[1] = 011
This means that the first and second switch can light up either the second or third lights. Upon encountering the second photograph (011, 011). wiring is updated as follows:
wiring[1] = 011 & 011 = 011
wiring[2] = 011
Now observe that the state of wiring indicates that all three switches can light up either the second and third lights. This is an inconsistency since 3 switches have to light up three lights, here we have three switches lighting up 2 lights.
I think this could be a solution, but I'm not sure, I can explain more tomorrow
import numpy as np
from operator import mul
def apparatus(n, m, x, y):
if not m:
return np.math.factorial(n) % 1000003
result = 1
tmp = np.matrix([False] * x.shape[1])
for i in xrange(x.shape[1]):
if tmp[0, i]:
continue
tmp0 = np.prod(x[:, i] == x, 0)
tmp1 = np.prod(x[:, i] == y, 0)
if np.sum(tmp1) != np.sum(tmp0):
return 0
result *= np.math.factorial(np.sum(tmp1))
result %= 1000003
tmp += tmp1
return result
x = np.matrix([[True, True, False]])
y = np.matrix([[False, True, True]])
print apparatus(3, 1, x, y)
x = np.matrix([[True, False, False, False], [False, False, False, False]])
y = np.matrix([[True, False, False, False], [False, False, True, False]])
print apparatus(4, 2, x, y)
print apparatus(1000, 0, [], [])

How to check if count of one part of the string is equal to another part with regex?

I have a strings like:
0011
01
000111
000111
I need to validate them like this: count of "0" must be identical to the count of "1". So "001" - invalid, "0011" - valid.
How can I do this with regex?
In Ruby, you can use subroutines:
m = /\b(0(\g<1>)?1)\b/.match('000111');
puts m;
Result of the demo:
000111
Or, you can just use capturing groups to match adjacent 0s and 1s, and then check the captured group length:
m = /(0+)(1+)/.match('0011');
puts m[1].length === m[2].length ? "True" : "False";
m = /(0+)(1+)/.match('00111');
puts m[1].length === m[2].length ? "True" : "False";
You may add ^ and $ to only match a string consisting of leading zeros and trailing 1s (m = /^(0+)(1+)$/.match('00111');).
Output of the demo program:
True
False

Simplifying a group of AND and OR clauses

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))

Resources