Where is nat base 10 converted to num base 2? - isabelle

For term "15::nat", the value 15 is automatically converted to the binary value (num.Bit1 (num.Bit1 (num.Bit1 num.One))). I would like to know where that's done, so I can know how it's done.
(Small update: I know that 15 is a type class numeral constant, which gets converted to binary Num.num, which gets mapped to nat, so maybe the nat is decimal, or maybe it's binary. However, my basic question remains the same. Where is the decimal to binary conversion done?)
I show below how I know about the conversion.
I define notation to show me that Num.numeral :: (num => 'a) is coercing 15 to Num.num.
abbreviation nat_of_numeral :: "num => nat" where
"nat_of_numeral n == (numeral n)"
notation nat_of_numeral ("n#N|_" [1000] 1000)
Next, 15 gets coerced to binary in a term command:
term "15::nat"
(*The output:*)
term "n#N|(num.Bit1 (num.Bit1 (num.Bit1 num.One))) :: nat"
And next, 15 gets coerced before it gets used in a proof goal:
lemma "15 = n#N|(num.Bit1 (num.Bit1 (num.Bit1 num.One)))" (*
goal (1 subgoal):
1. n#N|(num.Bit1 (num.Bit1 (num.Bit1 num.One))) =
n#N|(num.Bit1 (num.Bit1 (num.Bit1 num.One))) *)
by(rule refl)
The conversion seems to be decently fast, as shown by this:
(*140 digits: 40ms*)
term "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
::nat"
I also want to convert base 2 to base 10, but if I see how the above is done, it might show me how to do that.

Here's the overview of how I think it's done.
It starts in the Num.thy parse_translation, at the ML function numeral_tr.
In that function, there is the use of Lexicon.read_xnum of lexicon.ML, which takes a string argument.
I don't know the details, but string "15" is extracted from an expression like
"15 = n#N|(num.Bit1 (num.Bit1 (num.Bit1 num.One)))",
and fed to read_xnum, where there is this equivalency:
Lexicon.read_xnum "15" = {leading_zeros = 0, radix = 10, value = 15}
In read_xnum the function Library.read_radix_int of library.ML is used, and it takes as arguments an integer radix and a list of digits, such as shown in this equivalency:
Library.read_radix_int 10 ["1","5"] = (15, []);
Next, the conversion from 15 to (num.Bit1 (num.Bit1 (num.Bit1 num.One))) is a result of IntInf.quotRem in the parse_translation.
This takes me out of convenient HTML linking for isabelle.in.tum.de/repos.
IntInf.quotRem is in Isabelle2013-2\contrib\polyml-5.5.1-1\src\basis\IntInf.sml, and is defined as
val quotRem: int*int->int*int = RunCall.run_call2C2 POLY_SYS_quotrem,
which leads to Isabelle2013-2\contrib\polyml-5.5.1-1\src\basis\RuntimeCalls.ML line 83:
val POLY_SYS_quotrem = 104 (* DCJM 05/03/10 *).
For Windows that takes me to Isabelle2013-2\contrib\polyml-5.5.1-1\src\libpolyml\x86asm.asm line 1660, though I could be leaving out some important details:
quotrem_really_long:
MOVL Reax,Redi
CALLMACRO CALL_IO POLY_SYS_quotrem
CALLMACRO RegMask quotrem,(M_Reax OR M_Redi OR M_Redx OR Mask_all).
I think that's enough of an overview to answer my question. A string "15" is converted to an ML integer, and then some assembly language level quotient/remainder division is used to convert 15 to binary Num.num.
I'm actually only interested in how "15" is converted to 15 in read_radix_int, and whether the details of that function will help me. I explain the application more below.
From here, I put in more detail for myself, to put in a nice form much of the information I collected.
What's sort of the deal
I start with a binary number as a bool list, something like [True, True, True, True] for binary 15, though here, I simplify it in some ways.
That then gets converted to something like [[True, False, True, False], [True, False, True]], which is decimal 15.
The real problem can be finding the right search phrase
Searching on something like "decimal to binary conversion" returns links to a lot of basic math algorithms, which aren't what I'm looking for.
Normal programming conversions aren't what I need either, which is just making explicit the underlying fact that integers are already in binary form:
Convert from base 10 to base 2 using bitwise operations
C: Convert decimal to binary
Finally, other searches led me to the right word, "radix". Additionally, I resorted to doing searches on how things are done in C, where bit shifts are what I'm trying to tie into, though these may not be what I need:
Binary to decimal and decimal to binary base conversion using bitwise operators in C
C Program to Convert Decimal to Binary using Bitwise AND operator
Radix leading back to Num.thy
"Radix" took me back to Num.thy, which is where I thought the action might be, but hadn't seen anything that was obvious to me.
I include some source from Num.thy, lexicon.ML, and IntInf.sml:
(* THE TWO MAIN EXTERNAL FUNCTIONS IN THE TRANSLATIONS: read_xnum, quotRem *)
ML{*
Lexicon.read_xnum; (* string ->
{leading_zeros: int, radix: int, value: int}.*)
Lexicon.read_xnum "15"; (* {leading_zeros = 0, radix = 10, value = 15}.*)
Lexicon.read_xnum "15" = {leading_zeros = 0, radix = 10, value = 15};
IntInf.quotRem; (* int * int -> int * int.*)
IntInf.quotRem (5,3); (* (1, 2) *)
*}
parse_translation {* (* Num.thy(293) *)
let
fun num_of_int n =
if n > 0 then
(case IntInf.quotRem (n, 2) of
(0, 1) => Syntax.const #{const_name One}
| (n, 0) => Syntax.const #{const_name Bit0} $ num_of_int n
| (n, 1) => Syntax.const #{const_name Bit1} $ num_of_int n)
else raise Match
val pos = Syntax.const #{const_name numeral}
val neg = Syntax.const #{const_name neg_numeral}
val one = Syntax.const #{const_name Groups.one}
val zero = Syntax.const #{const_name Groups.zero}
fun numeral_tr [(c as Const (#{syntax_const "_constrain"}, _)) $ t $ u] =
c $ numeral_tr [t] $ u
| numeral_tr [Const (num, _)] =
let
val {value, ...} = Lexicon.read_xnum num;
in
if value = 0 then zero else
if value > 0
then pos $ num_of_int value
else neg $ num_of_int (~value)
end
| numeral_tr ts = raise TERM ("numeral_tr", ts);
in [("_Numeral", K numeral_tr)] end
*}
ML{* (* lexicon.ML(367) *)
(* read_xnum: hex/bin/decimal *)
local
val ten = ord "0" + 10;
val a = ord "a";
val A = ord "A";
val _ = a > A orelse raise Fail "Bad ASCII";
fun remap_hex c =
let val x = ord c in
if x >= a then chr (x - a + ten)
else if x >= A then chr (x - A + ten)
else c
end;
fun leading_zeros ["0"] = 0
| leading_zeros ("0" :: cs) = 1 + leading_zeros cs
| leading_zeros _ = 0;
in
fun read_xnum str =
let
val (sign, radix, digs) =
(case Symbol.explode (perhaps (try (unprefix "#")) str) of
"0" :: "x" :: cs => (1, 16, map remap_hex cs)
| "0" :: "b" :: cs => (1, 2, cs)
| "-" :: cs => (~1, 10, cs)
| cs => (1, 10, cs));
in
{radix = radix,
leading_zeros = leading_zeros digs,
value = sign * #1 (Library.read_radix_int radix digs)}
end;
end;
*}
ML{* (* IntInf.sml(42) *)
val quotRem: int*int->int*int = RunCall.run_call2C2 POLY_SYS_quotrem
*}
A big part of what I was looking for; radix again
(* THE FUNCTION WHICH TRANSLATES A LIST OF DIGITS/STRINGS TO A ML INTEGER *)
ML{*
Library.read_radix_int; (* int -> string list -> int * string list *)
Library.read_radix_int 10 ["1","5"]; (* (15, []): int * string list.*)
Library.read_radix_int 10 ["1","5"] = (15, []);
*}
ML{* (* library.ML(670) *)
fun read_radix_int radix cs =
let
val zero = ord "0";
val limit = zero + radix;
fun scan (num, []) = (num, [])
| scan (num, c :: cs) =
if zero <= ord c andalso ord c < limit then
scan (radix * num + (ord c - zero), cs)
else (num, c :: cs);
in scan (0, cs) end;
*}
The low-level division action
There's the high-level Integer.div_mod in integer.ML, which wasn't used for the translation above:
fun div_mod x y = IntInf.divMod (x, y);
In Isabelle2013-2\contrib\polyml-5.5.1-1\src\basis\IntInf.sml, the higher-level divMod can be compared to the lower-level quotRem:
ML{* (* IntInf.sml(42) *)
val quotRem: int*int->int*int = RunCall.run_call2C2 POLY_SYS_quotrem
(* This should really be defined in terms of quotRem. *)
fun divMod(i, j) = (i div j, i mod j)
*}
With the low-level action for quotRem apparently being done at the assembly language level:
ML{* (* RuntimeCalls.ML(83) *)
val POLY_SYS_quotrem = 104 (* DCJM 05/03/10 *)
*}
(* x86asm.asm(1660)
quotrem_really_long:
MOVL Reax,Redi
CALLMACRO CALL_IO POLY_SYS_quotrem
CALLMACRO RegMask quotrem,(M_Reax OR M_Redi OR M_Redx OR Mask_all)
*)
These various forms of div and mod are important to me.
I'm thinking that div and mod are to be avoided if possible, but tying into quotRem would be the way to go, I think, if division is unavoidable.

Related

Unexpected output type

I am doing practice with F#. I am trying to create a simple program capable to find me out a couple of prime numbers that, summed together, equal a natural number input. It is the Goldbach conjecture. A single couple of primes will be enough. We will assume the input to be a even number.
I first created a function to check if a number is prime:
let rec isPrime (x: int) (i: int) :bool =
match x % i with
| _ when float i > sqrt (float x) -> true
| 0 -> false
| _ -> isPrime x (i + 1)
Then, I am trying to develop a function that (a) looks for prime numbers, (b) compare their sum with the input 'z' and (c) returns a tuple when it finds the two numbers. The function should not be correct yet, but I would get the reason behind this problem:
let rec sumPrime (z: int) (j: int) (k: int) :int * int =
match isPrime j, isPrime k with
| 0, 0 when j + k > z -> (0, 0)
| 0, 0 -> sumPrime (j + 1) (k + 1)
| _, 0 -> sumPrime j (k + 1)
| 0, _ -> sumPrime (j + 1) k
| _, _ -> if j + k < z then
sumPrime (j + 1) k
elif j + k = z then
(j, k)
The problem: even if I specified that the output should be a tuple :int * int the compiler protests, claiming that the expected output should be of type bool. When in trouble, I usually refer to F# for fun and profit, that i love, but this time I cannot find out the problem. Any suggestion is greatly appreciated.
Your code has three problems that I've spotted:
Your isPrime returns a bool (as you've specified), but your match expression in sumPrime is matching against integers (in F#, the Boolean value false is not the same as the integer value 0). Your match expression should look like:
match isPrime j, isPrime k with
| false, false when j + k > z -> (0, 0)
| false, false -> ...
| true, false -> ...
| false, true -> ...
| true, true -> ...
You have an if...elif expression in your true, true case, but there's no final else. By default, the final else of an if expression returns (), the unit type. So once you fix your first problem, you'll find that F# is complaining about a type mismatch between int * int and unit. You'll need to add an else condition to your final match case to say what to do if j + k > z.
You are repeatedly calling your sumPrime function, which takes three parameters, with just two parameters. That is perfectly legal in F#, since it's a curried language: calling sumPrime with two parameters produces the type int -> int * int: a function that takes a single int and returns a tuple of ints. But that's not what you're actually trying to do. Make sure you specify a value for z in all your recursive calls.
With those three changes, you should probably see your compiler errors go away.

For Loop Over a Recursive Call Ocaml

I'm working on an implementation of prime decomposition in OCaml. I am not a functional programmer; Below is my code. The prime decomposition happens recursively in the prime_part function. primes is the list of primes from 0 to num. The goal here being that I could type prime_part into the OCaml interpreter and have it spit out when n = 20, k = 1.
2 + 3 + 7
5 + 7
I adapted is_prime and all_primes from an OCaml tutorial. all_primes will need to be called to generate a list of primes up to b prior to prime_part being called.
(* adapted from http://www.ocaml.org/learn/tutorials/99problems.html *)
let is_prime n =
let n = abs n in
let rec is_not_divisor d =
d * d > n || (n mod d <> 0 && is_not_divisor (d+1)) in
n <> 1 && is_not_divisor 2;;
let rec all_primes a b =
if a > b then [] else
let rest = all_primes (a + 1) b in
if is_prime a then a :: rest else rest;;
let f elem =
Printf.printf "%d + " elem
let rec prime_part n k lst primes =
let h elem =
if elem > k then
append_item lst elem;
prime_part (n-elem) elem lst primes in
if n == 0 then begin
List.iter f lst;
Printf.printf "\n";
()
end
else
if n <= k then
()
else
List.iter h primes;
();;
let main num =
prime_part num 1 [] (all_primes 2 num)
I'm largely confused with the reclusive nature with the for loop. I see that List.ittr is the OCaml way, but I lose access to my variables if I define another function for List.ittr. I need access to those variables to recursively call prime_part. What is a better way of doing this?
I can articulate in Ruby what I'm trying to accomplish with OCaml. n = any number, k = 1, lst = [], primes = a list of prime number 0 to n
def prime_part_constructive(n, k, lst, primes)
if n == 0
print(lst.join(' + '))
puts()
end
if n <= k
return
end
primes.each{ |i|
next if i <= k
prime_part_constructive(n - i, i, lst+[i], primes)
}
end
Here are a few comments on your code.
You can define nested functions in OCaml. Nested functions have access to all previously defined names. So you can use List.iter without losing access to your local variables.
I don't see any reason that your function prime_part_constructive returns an integer value. It would be more idiomatic in OCaml for it to return the value (), known as "unit". This is the value returned by functions that are called for their side effects (such as printing values).
The notation a.(i) is for accessing arrays, not lists. Lists and arrays are not the same in OCaml. If you replace your for with List.iter you won't have to worry about this.
To concatenate two lists, use the # operator. The notation lst.concat doesn't make sense in OCaml.
Update
Here's how it looks to have a nested function. This made up function takes a number n and a list of ints, then writes out the value of each element of the list multiplied by n.
let write_mults n lst =
let write1 m = Printf.printf " %d" (m * n) in
List.iter write1 lst
The write1 function is a nested function. Note that it has access to the value of n.
Update 2
Here's what I got when I wrote up the function:
let prime_part n primes =
let rec go residue k lst accum =
if residue < 0 then
accum
else if residue = 0 then
lst :: accum
else
let f a p =
if p <= k then a
else go (residue - p) p (p :: lst) a
in
List.fold_left f accum primes
in
go n 1 [] []
It works for your example:
val prime_part : int -> int list -> int list list = <fun>
# prime_part 12 [2;3;5;7;11];;
- : int list list = [[7; 5]; [7; 3; 2]]
Note that this function returns the list of partitions. This is much more useful (and functional) than writing them out (IMHO).

Reversing an int in OCaml

I'm teaching myself OCaml, and the main resources I'm using for practice are some problem sets Cornell has made available from their 3110 class. One of the problems is to write a function to reverse an int (i.e: 1234 -> 4321, -1234 -> -4321, 2 -> 2, -10 -> -1 etc).
I have a working solution, but I'm concerned that it isn't exactly idiomatic OCaml:
let rev_int (i : int) : int =
let rec power cnt value =
if value / 10 = 0 then cnt
else power (10 * cnt) (value/10) in
let rec aux pow temp value =
if value <> 0 then aux (pow/10) (temp + (value mod 10 * pow)) (value / 10)
else temp in
aux (power 1 i) 0 i
It works properly in all cases as far as I can tell, but it just seems seriously "un-OCaml" to me, particularly because I'm running through the length of the int twice with two inner-functions. So I'm just wondering whether there's a more "OCaml" way to do this.
I would say, that the following is idiomatic enough.
(* [rev x] returns such value [y] that its decimal representation
is a reverse of decimal representation of [x], e.g.,
[rev 12345 = 54321] *)
let rev n =
let rec loop acc n =
if n = 0 then acc
else loop (acc * 10 + n mod 10) (n / 10) in
loop 0 n
But as Jeffrey said in a comment, your solution is quite idiomatic, although not the nicest one.
Btw, my own style, would be to write like this:
let rev n =
let rec loop acc = function
| 0 -> acc
| n -> loop (acc * 10 + n mod 10) (n / 10) in
loop 0 n
As I prefer pattern matching to if/then/else. But this is a matter of mine personal taste.
I can propose you some way of doing it:
let decompose_int i =
let r = i / 10 in
i - (r * 10) , r
This function allows me to decompose the integer as if I had a list.
For instance 1234 is decomposed into 4 and 123.
Then we reverse it.
let rec rev_int i = match decompose_int i with
| x , 0 -> 10 , x
| h , t ->
let (m,r) = rev_int t in
(10 * m, h * m + r)
The idea here is to return 10, 100, 1000... and so on to know where to place the last digit.
What I wanted to do here is to treat them as I would treat lists, decompose_int being a List.hd and List.tl equivalent.

All substrings that are sequences of characters using functional programming

As a followup to my earlier question on finding runs of the same character in a string, I would also like to find a functional algorithm to find all substrings of length greater than 2 that are ascending or descending sequences of letters or digits (e,g,: "defgh", "34567", "XYZ", "fedcba", "NMLK", 9876", etc.) in a character string ([Char]). The only sequences that I am considering are substrings of A..Z, a..z, 0..9, and their descending counterparts. The return value should be a list of (zero-based offset, length) pairs. I am translating the "zxcvbn" password strength algorithm from JavaScript (containing imperative code) to Scala. I would like to keep my code as purely functional as possible, for all the usual reasons given for writing in the functional programming style.
My code is written in Scala, but I can probably translate an algorithm in any of Clojure, F#, Haskell, or pseudocode.
Example: For the string qweABCD13987 would return [(3,4),(9,3)].
I have written a rather monsterous function that I will post when I again have access to my work computer, but I am certain that a more elegant solution exists.
Once again, thanks.
I guess a nice solution for this problem is really more complicated than it seems at first.
I'm no Scala Pro, so my solution is surely not optimal and nice, but maybe it gives you some ideas.
The basic idea is to compute the difference between two consecutive characters, afterwards it unfortunately gets a bit messy. Ask me if some of the code is unclear!
object Sequences {
val s = "qweABCD13987"
val pairs = (s zip s.tail) toList // if s might be empty, add a check here
// = List((q,w), (w,e), (e,A), (A,B), (B,C), (C,D), (D,1), (1,3), (3,9), (9,8), (8,7))
// assuming all characters are either letters or digits
val diff = pairs map {case (t1, t2) =>
if (t1.isLetter ^ t2.isLetter) 0 else t1 - t2} // xor could also be replaced by !=
// = List(-6, 18, 36, -1, -1, -1, 19, -2, -6, 1, 1)
/**
*
* #param xs A list indicating the differences between consecutive characters
* #param current triple: (start index of the current sequence;
* number of current elements in the sequence;
* number indicating the direction i.e. -1 = downwards, 1 = upwards, 0 = doesn't matter)
* #return A list of triples similar to the argument
*/
def sequences(xs: Seq[Int], current: (Int, Int, Int) = (0, 1, 0)): List[(Int, Int, Int)] = xs match {
case Nil => current :: Nil
case (1 :: ys) =>
if (current._3 != -1)
sequences(ys, (current._1, current._2 + 1, 1))
else
current :: sequences(ys, (current._1 + current._2 - 1, 2, 1)) // "recompute" the current index
case (-1 :: ys) =>
if (current._3 != 1)
sequences(ys, (current._1, current._2 + 1, -1))
else
current :: sequences(ys, (current._1 + current._2 - 1, 2, -1))
case (_ :: ys) =>
current :: sequences(ys, (current._1 + current._2, 1, 0))
}
sequences(diff) filter (_._2 > 1) map (t => (t._1, t._2))
}
It's always best to split a problem into several smaller subproblems. I wrote a solution in Haskell, which is easier for me. It uses lazy lists, but I suppose you can convert it to Scala either using streams or by making the main function tail recursive and passing the intermediate result as an argument.
-- Mark all subsequences whose adjacent elements satisfy
-- the given predicate. Includes subsequences of length 1.
sequences :: (Eq a) => (a -> a -> Bool) -> [a] -> [(Int,Int)]
sequences p [] = []
sequences p (x:xs) = seq x xs 0 0
where
-- arguments: previous char, current tail sequence,
-- last asc. start offset of a valid subsequence, current offset
seq _ [] lastOffs curOffs = [(lastOffs, curOffs - lastOffs)]
seq x (x':xs) lastOffs curOffs
| p x x' -- predicate matches - we're extending current subsequence
= seq x' xs lastOffs curOffs'
| otherwise -- output the currently marked subsequence and start a new one
= (lastOffs, curOffs - lastOffs) : seq x' xs curOffs curOffs'
where
curOffs' = curOffs + 1
-- Marks ascending subsequences.
asc :: (Enum a, Eq a) => [a] -> [(Int,Int)]
asc = sequences (\x y -> succ x == y)
-- Marks descending subsequences.
desc :: (Enum a, Eq a) => [a] -> [(Int,Int)]
desc = sequences (\x y -> pred x == y)
-- Returns True for subsequences of length at least 2.
validRange :: (Int, Int) -> Bool
validRange (offs, len) = len >= 2
-- Find all both ascending and descending subsequences of the
-- proper length.
combined :: (Enum a, Eq a) => [a] -> [(Int,Int)]
combined xs = filter validRange (asc xs) ++ filter validRange (desc xs)
-- test:
main = print $ combined "qweABCD13987"
Here is my approximation in Clojure:
We can transform the input string so we can apply your previous algorithm to find a solution. The alorithm wont be the most performant but I think you will have a more abstracted and readable code.
The example string can be transformed in the following way:
user => (find-serials "qweABCD13987")
(0 1 2 # # # # 7 8 # # #)
Reusing the previous function "find-runs":
user => (find-runs (find-serials "qweABCD13987"))
([3 4] [9 3])
The final code will look like this:
(defn find-runs [s]
(let [ls (map count (partition-by identity s))]
(filter #(>= (% 1) 3)
(map vector (reductions + 0 ls) ls))))
(def pad "#")
(defn inc-or-dec? [a b]
(= (Math/abs (- (int a) (int b))) 1 ))
(defn serial? [a b c]
(or (inc-or-dec? a b) (inc-or-dec? b c)))
(defn find-serials [s]
(map-indexed (fn [x [a b c]] (if (serial? a b c) pad x))
(partition 3 1 (concat pad s pad))))
find-serials creates a 3 cell sliding window and applies serial? to detect the cells that are the beginning/middle/end of a sequence. The string is conveniently padded so the window is always centered over the original characters.

Using Greatest Common Divisor fun

euclid :: Int -> Int
euclid n = length (filter (gcd n == 1) [1 .. n-1])
gcd :: Int -> Int -> Int
..
Your error comes from "gcd x 0 = x". The "x :: Int" is the inferred result but the type declaration of "gcd :: Int->Int->Bool" expects Bool. I expect that "gcd x 0 = (x==1)" is what you ought to have typed.
Assuming you're looking for Euler's totient function, simply call
euler_fi1 n = length $ filter ((==1).(gcd n)) [1..n-1]
The linked WP article gives a formula for calculating this directly:
euler_fi n = let
fs = Data.List.nub $ factorize n
pr = n * product [p-1 | p <- fs]
in Data.List.foldl' div pr fs
You'll need a factorize function for that:
factorize n | n > 1 = go n (2:[3,5..]) where
go n ds#(d:t)
| d*d > n = [n]
| r == 0 = d : go q ds
| otherwise = go n t
where
(q,r) = quotRem n d
Next optimization is to use primes list instead of (2:[3,5..]).

Resources