Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
complete-ads
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Gijs van Cuyck
complete-ads
Commits
b82573db
Commit
b82573db
authored
Oct 26, 2018
by
Gijs van Cuyck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
finalized debugging of splitting_tree code. splitting tree generation tested on small benchmarks.
parent
3481e128
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
72 additions
and
12 deletions
+72
-12
lib/splitting_tree.cpp
lib/splitting_tree.cpp
+30
-9
lib/splitting_tree.hpp
lib/splitting_tree.hpp
+19
-3
lib/vector_printing.hpp
lib/vector_printing.hpp
+11
-0
src/main.cpp
src/main.cpp
+12
-0
No files found.
lib/splitting_tree.cpp
View file @
b82573db
...
...
@@ -145,6 +145,9 @@ void add_push_new_block(deque<work_set> &work_list, list<list<state>> const &new
}
}
assert
(
boom
.
children
.
size
()
==
boom
.
separators
.
size
());
if
(
boom
.
children
.
size
()
>
1
)
assert
(
boom
.
valid_map
.
size
()
>
0
);
assert
(
boom
.
states
.
size
()
==
accumulate
(
begin
(
boom
.
children
.
back
()),
end
(
boom
.
children
.
back
()),
0ul
,
[](
size_t
l
,
const
splitting_tree
&
r
)
{
...
...
@@ -217,16 +220,18 @@ splitting_tree create_splitting_tree(const mealy &g)
while
(
!
work_list
.
empty
())
{
splitting_tree
&
boom
=
work_list
.
front
().
work
;
unordered_set
<
state
>
&
valid_set
=
work_list
.
front
().
valid_states
;
unordered_set
<
state
>
valid_set
=
move
(
work_list
.
front
().
valid_states
)
;
bool
split_on_output
=
work_list
.
front
().
split_on_output
;
work_list
.
pop_front
();
//the state for which the current tree prioritizes validity.
//if there is no preference then the first one in the list is chosen.
//used when selecting a separator from multiple options.
//The preference is the one which is valid for valid_target, if it exists.
state
valid_target
=
0
;
state
valid_target
;
if
(
valid_set
.
size
()
>
0
)
valid_target
=
*
valid_set
.
begin
();
else
valid_target
=
boom
.
states
.
front
();
const
size_t
depth
=
boom
.
depth
;
...
...
@@ -275,12 +280,29 @@ splitting_tree create_splitting_tree(const mealy &g)
//the forced progress might open new options, for which we check first before we force progress again.
force_progress
=
false
;
//copy the valid set so we can delete things from it without affecting the tree.
unordered_set
targets
(
valid_set
);
assert
(
valid_set
.
size
()
==
0
||
[
&
valid_set
](
splitting_tree
&
boom
)
{
for
(
state
s
:
valid_set
)
{
if
(
std
::
find
(
boom
.
states
.
begin
(),
boom
.
states
.
end
(),
s
)
!=
boom
.
states
.
end
())
{
continue
;
}
else
{
return
false
;
}
}
return
true
;
}(
boom
));
//the set of all states for which we want to be valid: the intersection between valid_set and boom.states.
unordered_set
<
state
>
targets
;
//an empty set actually means its valid for everything, but you cant delete states from an empty set.
//So we explicitly fill it here.
if
(
targets
.
size
()
<
1
)
fill_set
(
targets
,
N
);
if
(
valid_set
.
size
()
<
1
)
targets
=
unordered_set
<
state
>
(
boom
.
states
.
begin
(),
boom
.
states
.
end
());
else
targets
=
unordered_set
<
state
>
(
valid_set
);
//a list of all the splits that were made.
//they are saved in a list so that they can be modified if required before they are pushed onto the work_list.
...
...
@@ -379,7 +401,7 @@ splitting_tree create_splitting_tree(const mealy &g)
unordered_set
<
state
>
new_valid_set
=
is_valid_for
(
N
,
g
,
new_blocks
,
symbol
);
bool
updated_separator
=
false
;
if
(
new_valid_set
.
size
()
>
best_separator_value
)
if
(
best_separator_value
==-
1
||
new_valid_set
.
size
()
>
best_separator_value
)
{
best_separator
=
word
;
best_separator_value
=
new_valid_set
.
size
();
...
...
@@ -455,8 +477,7 @@ splitting_tree create_splitting_tree(const mealy &g)
successor_states
[
apply
(
g
,
state
,
symbol
).
to
]
=
true
;
}
//the state to which the valid target moves when given the selected symbol as input.
state
valid_target_image
=
apply
(
g
,
valid_target
,
symbol
).
to
;
state
valid_target_image
=
apply
(
g
,
valid_target
,
symbol
).
to
;
const
auto
&
oboom
=
lca
(
root
,
[
&
successor_states
](
state
state
)
->
bool
{
...
...
lib/splitting_tree.hpp
View file @
b82573db
...
...
@@ -19,8 +19,22 @@ struct splitting_tree {
const
std
::
vector
<
splitting_tree
>
&
get_children
(
state
s
)
const
{
if
(
children
.
size
()
<
1
)
throw
std
::
runtime_error
(
"get_children called when there were no children"
);
else
if
(
children
.
size
()
==
1
)
return
children
.
front
();
else
if
(
valid_map
.
size
()
<
1
||
valid_map
.
count
(
s
)
<
1
)
return
children
[
0
];
throw
std
::
runtime_error
(
"valid map does not contain required information"
);
else
return
children
[
valid_map
.
at
(
s
)];
}
//returns the first set of children if the target is not found in valid list.
//otherwise behaves exactly the same as get_children.
//this behaviour is required for the lca_impl, but might mask errors if used elsewere.
const
std
::
vector
<
splitting_tree
>
&
get_children_reliably
(
state
s
)
const
{
if
(
children
.
size
()
<
1
)
throw
std
::
runtime_error
(
"get_children called when there were no children"
);
else
if
(
valid_map
.
count
(
s
)
<
1
)
return
children
.
front
();
else
return
children
[
valid_map
.
at
(
s
)];
}
...
...
@@ -28,8 +42,10 @@ struct splitting_tree {
const
word
&
get_separator
(
state
s
)
const
{
if
(
children
.
size
()
<
1
)
throw
std
::
runtime_error
(
"get_separator called when there were no separators"
);
else
if
(
children
.
size
()
==
1
)
return
separators
.
front
();
else
if
(
valid_map
.
size
()
<
1
||
valid_map
.
count
(
s
)
<
1
)
return
separators
[
0
]
;
throw
std
::
runtime_error
(
"valid map does not contain required information"
)
;
else
return
separators
[
valid_map
.
at
(
s
)];
}
...
...
@@ -60,7 +76,7 @@ size_t lca_impl(splitting_tree const & node, Fun && f, Store && store, state val
// we return this (it's the lca), if more children return a non-nil
// node, then we are the lca
size_t
count
=
0
;
for
(
const
splitting_tree
&
c
:
node
.
get_children
(
valid_target
))
{
for
(
const
splitting_tree
&
c
:
node
.
get_children
_reliably
(
valid_target
))
{
auto
inner_count
=
lca_impl
(
c
,
f
,
store
,
valid_target
);
if
(
inner_count
>
0
)
count
++
;
}
...
...
lib/vector_printing.hpp
View file @
b82573db
...
...
@@ -7,6 +7,7 @@
#include <string>
#include <sstream>
#include <vector>
/// \brief turns a vector of printable objects into a string, putting a sepperator between every two elements and
/// a concluder after the last one.
...
...
@@ -34,4 +35,14 @@ std::string join(InputIt begin,
return
ss
.
str
();
}
template
<
typename
T
>
std
::
ostream
&
operator
<<
(
std
::
ostream
&
s
,
std
::
vector
<
T
>
v
)
{
for
(
int
i
=
0
;
i
<
v
.
size
();
i
++
)
{
s
<<
i
<<
" = "
<<
v
[
i
]
<<
"
\n
"
;
}
return
s
;
}
#endif //COMPLETE_ADS_PRINTING_H
src/main.cpp
View file @
b82573db
...
...
@@ -4,6 +4,7 @@
#include <read_mealy.hpp>
#include <splitting_tree.hpp>
#include "readable_splitting_tree.hpp"
#include "vector_printing.hpp"
#include <algorithm>
...
...
@@ -58,6 +59,9 @@ struct main_options {
unsigned
long
k_max
=
1
;
// 3 means 2 extra states. currently not supported
unsigned
long
seed
=
0
;
// 0 for unset/noise. currently not supported
//"../examples/coffe_machine.dot";
//"../examples/lee_yannakakis_difficult.dot";
//"../examples/lee_yannakakis_distinguishable.dot";
string
input_filename
=
"../examples/coffe_machine.dot"
;
string
output_filename
=
""
;
};
...
...
@@ -166,6 +170,14 @@ int main(int argc, char * argv[]){
splitting_tree
complete_splitting_tree
=
create_splitting_tree
(
machine
);
vector
<
string
>
input_translation
=
create_reverse_map
(
translation
.
input_indices
);
vector
<
string
>
state_translation
=
create_reverse_map
(
translation
.
state_indices
);
ofstream
translation_file
(
output_directory
+
"translations.txt"
);
translation_file
<<
"input translation
\n
"
;
translation_file
<<
input_translation
;
translation_file
<<
"
\n
state translation
\n
"
;
translation_file
<<
state_translation
;
translation_file
.
close
();
readable_splitting_tree
translated_tree
=
translate_splitting_tree
(
complete_splitting_tree
,
input_translation
,
state_translation
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment