source: CIVL/examples/verifyThisProblems/lrs.c@ 0cdc417

1.23 2.0 main test-branch
Last change on this file since 0cdc417 was 6247c10, checked in by Yihao Yan <yihaoyan1@…>, 10 years ago

update verifyThis problems in civl example

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@3164 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 3.2 KB
Line 
1/*
2Author: Yihao Yan
3
4Download LCP.zip from: http://fm2012.verifythis.org/challenges
5
6-----------------
7Problem background:
8
9Together with a suffix array, LCP can be used to solve interesting text
10problems, such as finding the longest repeated substring (LRS) in a text.
11
12A suffix array (for a given text) is an array of all suffixes of the
13text. For the text [7,8,8,6], the suffix array is
14[[7,8,8,6],
15 [8,8,6],
16 [8,6],
17 [6]]
18
19Typically, the suffixes are not stored explicitly as above but
20represented as pointers into the original text. The suffixes in a suffix
21array are sorted in lexicographical order. This way, occurrences of
22repeated substrings in the original text are neighbors in the suffix
23array.
24
25-----------------
26Verification task:
27
28Implement longest repeated substring function and verify that it does so correctly.
29
30-----------------
31Result:
32
33For all strings with length less than 5, the lrs function returns an index i and a length l.
34The verification shows that the sub string with length l starting from index i is repeated in
35the original string and also, there exists no repeated string with length greater than l. Therefore
36the implemented function lrs behaves correctly.
37*/
38
39#include <stdlib.h>
40#include <stdio.h>
41#include <civlc.cvh>
42#include <assert.h>
43
44$input int N_BOUND = 5;
45$input int N;
46$input int X1[N];
47$assume (N < N_BOUND && N >= 0);
48
49int lcp1(int *arr, int n, int x, int y) {
50 int l=0;
51
52 while (x+l<n && y+l<n && arr[x+l]==arr[y+l]) {
53 l++;
54 }
55 return l;
56}
57
58int compare(int *a, int n, int x, int y) {
59 if (x == y) return 0;
60
61 int l = 0;
62
63 while (x+l<n && y+l<n && a[x+l] == a[y+l]) {
64 l++;
65 }
66 if (x+l == n) return -1;
67 if (y+l == n) return 1;
68 if (a[x+l] < a[y+l]) return -1;
69 if (a[x+l] > a[y+l]) return 1;
70 return -2;
71}
72
73void sort(int *a, int n, int *data) {
74 for(int i = 0; i < n + 0; i++) {
75 for(int j = i; j > 0 && compare(a, n, data[j - 1], data[j]) > 0; j--) {
76 int b = j - 1;
77 int t = data[j];
78
79 data[j] = data[b];
80 data[b] = t;
81 }
82 }
83}
84
85int lcp2(int *a, int n, int index, int* suffixes) {
86 return lcp1(a,n,suffixes[index], suffixes[index-1]);
87}
88
89/**
90result[0]: index
91result[1]: length
92*/
93void lrs(int* a, int n, int *result) {
94 int suffixes[n];
95
96 for(int i=0; i<n; i++) {
97 suffixes[i] = i;
98 }
99 sort(a, n, suffixes);
100 for(int i=1; i<n; i++) {
101 int len = lcp2(a, n, i,suffixes);
102
103 if(len > result[1]) {
104 result[0] = suffixes[i];
105 result[1] = len;
106 }
107 }
108}
109
110int main(){
111 int* result = (int*)malloc(2* sizeof(int));
112
113 result[0] = 0;
114 result[1] = 0;
115 lrs(X1, N, result);
116
117 int index = result[0];
118 int maxLen = result[1];
119
120 if(N > 1) {
121 $assert($exists {int k | k >= 0 && k <= N - maxLen && k != index}(
122 $forall {i = 0 .. maxLen-1} X1[k+i] == X1[index+i]
123 ));
124 $assert(!($exists {int k | k >= 0 && k <= N - maxLen - 1}(
125 $exists {int j | j >= 0 && j <= N - maxLen - 1 && j != k}(
126 $forall {i = 0 .. maxLen} X1[k+i] == X1[j+i]
127 ))));
128 }else{
129 $assert(index == 0 && maxLen == 0);
130 }
131
132 free(result);
133 return 0;
134}
Note: See TracBrowser for help on using the repository browser.