source: CIVL/examples/verifyThis/lrs.c

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

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

  • Property mode set to 100644
File size: 3.3 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-----------------
39command: minor changes
40*/
41
42#include <stdlib.h>
43#include <stdio.h>
44#include <civlc.cvh>
45#include <assert.h>
46
47$input int N_BOUND = 5;
48$input int N;
49$assume (N < N_BOUND && N > 0);
50$input int X1[N];
51
52int lcp1(int *arr, int n, int x, int y) {
53 int l=0;
54
55 while (x+l<n && y+l<n && arr[x+l]==arr[y+l]) {
56 l++;
57 }
58 return l;
59}
60
61int compare(int *a, int n, int x, int y) {
62 if (x == y) return 0;
63
64 int l = 0;
65
66 while (x+l<n && y+l<n && a[x+l] == a[y+l]) {
67 l++;
68 }
69 if (x+l == n) return -1;
70 if (y+l == n) return 1;
71 if (a[x+l] < a[y+l]) return -1;
72 if (a[x+l] > a[y+l]) return 1;
73 return -2;
74}
75
76void sort(int *a, int n, int *data) {
77 for(int i = 0; i < n + 0; i++) {
78 for(int j = i; j > 0 && compare(a, n, data[j - 1], data[j]) > 0; j--) {
79 int b = j - 1;
80 int t = data[j];
81
82 data[j] = data[b];
83 data[b] = t;
84 }
85 }
86}
87
88int lcp2(int *a, int n, int index, int* suffixes) {
89 return lcp1(a,n,suffixes[index], suffixes[index-1]);
90}
91
92/**
93result[0]: index
94result[1]: length
95*/
96void lrs(int* a, int n, int *result) {
97 int suffixes[n];
98
99 for(int i=0; i<n; i++) {
100 suffixes[i] = i;
101 }
102 sort(a, n, suffixes);
103 for(int i=1; i<n; i++) {
104 int len = lcp2(a, n, i,suffixes);
105
106 if(len > result[1]) {
107 result[0] = suffixes[i];
108 result[1] = len;
109 }
110 }
111}
112
113int main(){
114 int* result = (int*)malloc(2* sizeof(int));
115
116 result[0] = 0;
117 result[1] = 0;
118 lrs(X1, N, result);
119
120 int index = result[0];
121 int maxLen = result[1];
122
123 if(N > 1) {
124 $assert($exists (int k | k >= 0 && k <= N - maxLen && k != index)
125 ($forall (int i: 0 .. maxLen-1) X1[k+i] == X1[index+i])
126 );
127 $assert(!($exists (int k | k >= 0 && k <= N - maxLen - 1)
128 ($exists (int j | j >= 0 && j <= N - maxLen - 1 && j != k)
129 ($forall (int i: 0 .. maxLen) X1[k+i] == X1[j+i])
130 )
131 )
132 );
133 }else{
134 $assert(index == 0 && maxLen == 0);
135 }
136
137 free(result);
138 return 0;
139}
Note: See TracBrowser for help on using the repository browser.