I was looking for a Pascal equivalent for (for example) the php's substr function, which works like this:
$new_string = substr('abcdef', 1, 3); // returns 'bcd'
I've already found it, but I always take excessively long to do so, so I'm posting the answer for others like me to be able to easily find it.
You can use the function copy. The syntax goes:
copy(string, start, length);
Strings in Pascal seem to be indexed starting from the 1, so the following:
s1 := 'abcdef';
s2 := copy(s1, 2, 3);
will result in
s2 == 'bcd'.
Hope this helps someone.
Freepascal also has a Copy function:
T:='1234567';
S:=Copy (T,1,2); { S:='12' }
S:=Copy (T,4,2); { S:='45' }
S:=Copy (T,4,8); { S:='4567' }
I recommend you see Lazarus IDE.
function substring(s: string; a, b: integer): string;
var len: integer;
procedure swap(var a, b: integer);
var temp: integer;
begin
temp:= a;
a:= b;
b:= temp;
end;
begin
if (a > b) then
swap(a, b);
len:= length(s);
if ((len = 0) or ((a < 1) and (b < 1)) or
((a > len) and (b > len))) then
begin
substring:= '';
end
else
begin
if (a < 1) then
a:= 1;
if (b > len) then
b:= len;
substring:= copy(s, a, b);
end;
end;
Related
method atoi(a:array<char>) returns(r:int)
requires a.Length>0
requires forall k :: 0<= k <a.Length ==> (a[k] as int) - ('0' as int) <= 9
ensures ??
{
var j:int := 0;
while j < a.Length
invariant ??
{
r := r*10 + (a[j] as int) - ('0' as int);
j := j + 1;
}
}
How to write "ensures" for the atoi method and "invariant" for the while loops in dafny?
I express the idea "each bit of the return value corresponds to each bit of the character array" as following:
// Ten to the NTH power
// e.g.: ten_pos_pow(2) == 10*10 == 100
function ten_pos_pow(p:int):int
requires p>=0
ensures ten_pos_pow(p) >= 1
{
if p==0 then 1 else
10*ten_pos_pow(p-1)
}
// Count from right to left, the ith digit of integer v (i starts from zero)
// e.g.: num_in_int(123,0) == 3 num_in_int(123,1) == 2 num_in_int(123,2) == 1
function num_in_int(v:int,i:int) : int
requires i>=0
{
(v % ten_pos_pow(i+1))/ten_pos_pow(i)
}
method atoi(a:array<char>) returns(r:int)
requires a.Length>0
requires forall k :: 0<= k <a.Length ==> (a[k] as int) - ('0' as int) <= 9
ensures forall k :: 0<= k < a.Length ==> ((a[k] as int) - ('0' as int)) == num_in_int(r,a.Length-k-1)
{
var i:int := 0;
r := 0;
while i < a.Length
invariant 0<= i <= a.Length
invariant forall k :: 0<= k < i ==> ((a[k] as int) - ('0' as int)) == num_in_int(r,i-k-1) // loop invariant violation
{
r := r*10 + (a[i] as int) - ('0' as int);
i := i + 1;
}
}
But the loops invariant violation. How to write a correct and provable specification?
This lemma verifies, but it raises the warning Not triggers found:
lemma multisetPreservesGreater (a:seq<int>, b:seq<int>, c:int, f:int, x:int)
requires |a|==|b| && 0 <= c <= f + 1 <= |b|
requires (forall j :: c <= j <= f ==> a[j] >= x)
requires multiset(a[c..f+1]) == multiset(b[c..f+1])
ensures (forall j :: c <= j <= f ==> b[j] >= x)
{
assert (forall j :: j in multiset(a[c..f+1]) ==> j in multiset(b[c..f+1]));
}
I do not know how to instantiate this trigger (cannot instantiate it as a function, or can I?). Any help?
Edit: Maybe I can instantiate a method f such that takes an array and inserts it in a multiset, and therefore I can trigger f(a), but that does not mention i. I will try.
Here's one way to transform the program so that there are no trigger warnings.
function SeqRangeToMultiSet(a: seq<int>, c: int, f: int): multiset<int>
requires 0 <= c <= f + 1 <= |a|
{
multiset(a[c..f+1])
}
lemma multisetPreservesGreater (a:seq<int>, b:seq<int>, c:int, f:int, x:int)
requires |a|==|b| && 0 <= c <= f + 1 <= |b|
requires (forall j :: c <= j <= f ==> a[j] >= x)
requires multiset(a[c..f+1]) == multiset(b[c..f+1])
ensures (forall j :: c <= j <= f ==> b[j] >= x)
{
assert forall j :: j in SeqRangeToMultiSet(a, c, f) ==> j in SeqRangeToMultiSet(b, c, f);
forall j | c <= j <= f
ensures b[j] >= x
{
assert b[j] in SeqRangeToMultiSet(b, c, f);
}
}
The point is that we introduce the function SeqRangeToMultiSet to stand for a subexpression that is not a valid trigger (because it contains arithmetic). Then SeqRangeToMultiSet itself can be the trigger.
The downside of this approach is that it decreases automation. You can see that we had to add a forall statement to prove the postcondition. The reason is that we need to mention the trigger, which does not appear in the post condition.
I am passing Logical Foundations course and became stuck upon the last excersize of Basics:
Having binary number write a converter to it's unary representation:
Inductive bin : Type :=
| Z
| A (n : bin)
| B (n : bin).
Fixpoint bin_to_nat (m:bin) : nat :=
(* What to do here? *)
I solved the problem with a recursive function in C. The only thing, I used "0" istead of "A" and "1" instead of "B".
#include <stdio.h>
unsigned int pow2(unsigned int power)
{
if(power != 0)
return 2 << (power - 1);
else
return 1;
}
void rec_converter(char str[], size_t i)
{
if(str[i] == 'Z')
printf("%c", 'Z');
else if(str[i] == '0')
rec_converter(str, ++i);
else if(str[i] == '1')
{
unsigned int n = pow2(i);
for (size_t j = 0; j < n; j++)
{
printf("%c", 'S');
}
rec_converter(str, ++i);
}
}
int main(void)
{
char str[] = "11Z";
rec_converter(str, 0);
printf("\n");
return 0;
}
My problem now is how to write this code in coq:
unsigned int n = pow2(i);
for (size_t j = 0; j < n; j++)
{
printf("%c", 'S');
}
rec_converter(str, ++i);
The main difference between your code and the Coq code is that the Coq code ought to return the natural number, rather than printing it. That means we'll need to keep track of everything that your solution printed and return the result all at once.
Since printing an S means that the answer is the successor of whatever else is printed, we'll need a function that can take the 2^(n)th successor of a natural number. There are various ways to do this, but I'd suggest recursion on n and noting that the 2^(n + 1)th successor of x is the 2^(n)th successor of the 2^(n)th successor of x.
That should be enough to get what you want.
unsigned int n = pow2(i);
for (size_t j = 0; j < n; j++)
{
printf("%c", 'S');
}
rec_converter(str, ++i);
can be written (in pseudo-Coq) as
pow2_succ i (rec_converter str (S i)).
However, one other thing to note: you may not be able to directly access the ith "character" of the input, but this shouldn't be a problem. When you write your function as a Fixpoint
Fixpoint rec_converter (n: bin) (i: nat): nat :=
match n with
| Z => 0
| A m => ...
| B m => ...
end.
the first "character" of m will be the second "character" of the original input. So you'll just need to access the first "character", which is exactly what a Fixpoint does.
For the question on computing powers of 2, you should look at the following file, provided in the Coq libraries (at least up to version 8.9):
https://coq.inria.fr/distrib/current/stdlib/Coq.Init.Nat.html
This file contains a host of functions around the natural numbers, they could all be used as illustrations about how to program with Coq and this datatype.
Fixpoint bin_to_nat (m:bin) : nat :=
match m with
| Z => O
| A n =>2 * (bin_to_nat n)
| B n =>2 * (bin_to_nat n) + 1
end.
see: coq art's 2004. P167-P168. ( How to understand 'positive' type in Coq)
I'm migrating from Java to Scala and I am trying to come up with the procedure merge for mergesort algorithm. My solution:
def merge(src: Array[Int], dst: Array[Int], from: Int,
mid: Int, until: Int): Unit = {
/*
* Iteration of merge:
* i - index of src[from, mid)
* j - index of src[mid, until)
* k - index of dst[from, until)
*/
#tailrec
def loop(i: Int, j: Int, k: Int): Unit = {
if (k >= until) {
// end of recursive calls
} else if (i >= mid) {
dst(k) = src(j)
loop(i, j + 1, k + 1)
} else if (j >= until) {
dst(k) = src(j)
loop(i + 1, j, k + 1)
} else if (src(i) <= src(j)) {
dst(k) = src(i);
loop(i + 1, j, k + 1)
} else {
dst(k) = src(j)
loop(i, j + 1, k + 1)
}
}
loop(from, mid, from)
}
seems to work, but it seems to me that it is written in quite "imperative" style
(despite i have used recursion and no mutable variables except for the arrays, for which the side effect is intended). I want something like this:
/*
* this code is not working and at all does the wrong things
*/
for (i <- (from until mid); j <- (mid until until);
k <- (from until until) if <???>) yield dst(k) = src(<???>)
But i cant come up with the proper solution of such kind. Can you please help me?
Consider this:
val left = src.slice(from, mid).buffered
val right = src.slice(mid, until).buffered
(from until until) foreach { k =>
dst(k) = if(!left.hasNext) right.next
else if(!right.hasNext || left.head < right.head) left.next
else right.next
}
I have just started learning Scala and sideways I am doing some algorithms also. Below is an implementation of merge sort in Scala. I know it isn't very "scala" in nature, and some might even reckon that I have tried to write java in scala. I am not totally familiar with scala, i just know some basic syntax and i keep googling if i need something more. So please give me some pointers on to what can i do in this code to make it more functional and in accord with scala conventions and best practices. Please dont just give correct/optimized code, i will like to do it myself. Any suggestions are welcomed !
def mergeSort(list: Array[Int]): Array[Int] = {
val len = list.length
if (len == 1) list
else {
var x, y = new Array[Int](len / 2)
val z = new Array[Int](len)
Array.copy(list, 0, x, 0, len / 2)
Array.copy(list, len / 2, y, 0, len / 2)
x = mergeSort(x)
y = mergeSort(y)
var i, j = 0
for (k <- 0 until len) {
if (j >= y.length || (i < x.length && x(i) < y(j))) {
z(k) = x(i)
i = i + 1
} else {
z(k) = y(j)
j = j + 1
}
}
z
}
}
[EDIT]
This code works fine and I have assumed for now that input array will always be of even length.
UPDATE
Removed vars x and y
def mergeSort(list: Array[Int]): Array[Int] = {
val len = list.length
if (len == 1) list
else {
val z = new Array[Int](len)
val x = mergeSort(list.dropRight(len/2))
val y = mergeSort(list.drop(len/2))
var i, j = 0
for (k <- 0 until len) {
if (j >= y.length || (i < x.length && x(i) < y(j))) {
z(k) = x(i)
i = i + 1
} else {
z(k) = y(j)
j = j + 1
}
}
z
}
}
Removing the var x,y = ... would be a good start to being functional. Prefer immutability to mutable datasets.
HINT: a method swap that takes two values and returns them ordered using a predicate
Also consider removing the for loop(or comprehension).