Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
VIGNET Pierre
cadbiom
Commits
9c001ea6
Commit
9c001ea6
authored
Nov 25, 2019
by
VIGNET Pierre
Browse files
[cmd] Fix typos
parent
ca679ad9
Changes
1
Hide whitespace changes
Inline
Side-by-side
command_line/cadbiom_cmd/solution_search.py
View file @
9c001ea6
...
...
@@ -38,12 +38,15 @@ import os
from
functools
import
partial
import
sys
import
itertools
as
it
# Multiprocessing
try
:
from
concurrent.futures
import
ProcessPoolExecutor
,
as_completed
except
ImportError
:
raise
ImportError
(
"No module named concurrent.futures.
\
You can try to install 'futures' module in Python 2.7"
)
raise
ImportError
(
"No module named concurrent.futures.
\n
"
"You can try to install 'futures' module in Python 2.7"
)
import
multiprocessing
as
mp
# Custom imports
...
...
@@ -58,6 +61,7 @@ class ErrorRep(object):
"""Cf class CompilReporter(object):
gt_gui/utils/reporter.py
"""
def
__init__
(
self
):
self
.
context
=
""
self
.
error
=
False
...
...
@@ -85,10 +89,10 @@ def logical_operator(elements, operator):
:type arg2: <str>
:rtype: <str>
"""
assert
operator
in
(
'
and
'
,
'
or
'
)
# print(operator + ": elements:", elements)
assert
operator
in
(
"
and
"
,
"
or
"
)
# print(operator + ": elements:", elements)
return
'('
+
" {} "
.
format
(
operator
).
join
(
elements
)
+
')'
return
"("
+
" {} "
.
format
(
operator
).
join
(
elements
)
+
")"
def
make_logical_formula
(
previous_frontier_places
,
start_prop
):
...
...
@@ -109,25 +113,26 @@ def make_logical_formula(previous_frontier_places, start_prop):
:rtype: <str>
"""
logical_and
=
partial
(
logical_operator
,
operator
=
'
and
'
)
logical_or
=
partial
(
logical_operator
,
operator
=
'
or
'
)
logical_and
=
partial
(
logical_operator
,
operator
=
"
and
"
)
logical_or
=
partial
(
logical_operator
,
operator
=
"
or
"
)
def
add_start_prop
(
prev_frontier_places_formula
):
"""Deal with start_prop if given"""
if
start_prop
and
prev_frontier_places_formula
:
return
start_prop
+
'
and (
'
+
prev_frontier_places_formula
+
')'
return
start_prop
+
"
and (
"
+
prev_frontier_places_formula
+
")"
elif
prev_frontier_places_formula
:
return
prev_frontier_places_formula
return
start_prop
mac_list
=
[
logical_and
(
frontier_places
)
for
frontier_places
in
previous_frontier_places
]
mac_list
=
[
logical_and
(
frontier_places
)
for
frontier_places
in
previous_frontier_places
]
if
mac_list
:
# Logical or between each line
return
add_start_prop
(
'
not(
'
+
logical_or
(
mac_list
)
+
')'
)
return
add_start_prop
(
''
)
return
add_start_prop
(
"
not(
"
+
logical_or
(
mac_list
)
+
")"
)
return
add_start_prop
(
""
)
def
get_dimacs_start_properties
(
mcla
,
previous_frontier_places
):
...
...
@@ -138,10 +143,12 @@ def get_dimacs_start_properties(mcla, previous_frontier_places):
for each new query.
"""
dimacs_start
=
list
()
[
dimacs_start
.
append
(
[
-
mcla
.
unfolder
.
var_dimacs_code
(
place
)
for
place
in
frontier_places
]
)
for
frontier_places
in
previous_frontier_places
]
[
dimacs_start
.
append
(
[
-
mcla
.
unfolder
.
var_dimacs_code
(
place
)
for
place
in
frontier_places
]
)
for
frontier_places
in
previous_frontier_places
]
def
search_entry_point
(
...
...
@@ -215,16 +222,17 @@ def search_entry_point(
if
mcla
.
reporter
.
error
:
raise
"Error during loading of file"
# Frontier places asked
if
continue_run
:
# Reload previous working files
try
:
## TODO: see docstring of read_mac_file
previous_frontier_places
=
read_mac_file
(
mac_file
)
LOGGER
.
info
(
"%s:: Reload previous frontier places: %s"
,
final_prop
,
len
(
previous_frontier_places
))
LOGGER
.
info
(
"%s:: Reload previous frontier places: %s"
,
final_prop
,
len
(
previous_frontier_places
),
)
except
IOError
:
LOGGER
.
warning
(
"%s:: mac file not found!"
,
final_prop
)
previous_frontier_places
=
set
()
...
...
@@ -232,14 +240,14 @@ def search_entry_point(
# New run
previous_frontier_places
=
set
()
# Compute the number of previously computed frontier places
current_nb_sols
=
len
(
previous_frontier_places
)
if
previous_frontier_places
else
0
if
current_nb_sols
>=
limit
:
# EXIT
LOGGER
.
info
(
"%s:: Reaching the limitation of the number of solutions!"
,
final_prop
)
LOGGER
.
info
(
"%s:: Reaching the limitation of the number of solutions!"
,
final_prop
)
return
## Find macs in an optimized way with find_macs() (see the doc for more info)
...
...
@@ -257,8 +265,7 @@ def search_entry_point(
## Find mac one by one with find_mac() (see the docstring for more info)
while
True
:
# Compute the formula of the next start_property
current_start_prop
=
make_logical_formula
(
previous_frontier_places
,
start_prop
)
current_start_prop
=
make_logical_formula
(
previous_frontier_places
,
start_prop
)
LOGGER
.
info
(
"%s:: Start property: %s"
,
final_prop
,
current_start_prop
)
ret
=
\
...
...
@@ -276,9 +283,9 @@ def search_entry_point(
# Add theese frontier places to set of previous ones
# (tuple is hashable)
previous_frontier_places
.
add
(
tuple
(
frontier_places
))
LOGGER
.
debug
(
"%s:: Prev frontier places: %s"
,
final_prop
,
previous_frontier_places
)
LOGGER
.
debug
(
"%s:: Prev frontier places: %s"
,
final_prop
,
previous_frontier_places
)
# If set to True (not default), search all macs with
# less or equal the maxium of steps defined with the argument `steps`.
...
...
@@ -291,8 +298,9 @@ def search_entry_point(
current_nb_sols
+=
1
if
current_nb_sols
>=
limit
:
# EXIT
LOGGER
.
info
(
"%s:: Reaching the limitation of the number of solutions!"
,
final_prop
)
LOGGER
.
info
(
"%s:: Reaching the limitation of the number of solutions!"
,
final_prop
)
return
LOGGER
.
debug
(
"%s:: Next solution will be in %s steps"
,
final_prop
,
steps
)
...
...
@@ -337,12 +345,12 @@ def find_macs(mcla,
# Save MAC and timings
LOGGER
.
debug
(
"%s:: Save MAC and timings..."
,
final_prop
)
with
open
(
mac_complete_file
,
'a'
)
as
file
:
with
open
(
mac_complete_file
,
"a"
)
as
file
:
frontier_sol
.
save
(
file
)
# Save MAC
LOGGER
.
debug
(
"%s:: Save next MAC: %s"
,
final_prop
)
with
open
(
mac_file
,
'a'
)
as
file
:
with
open
(
mac_file
,
"a"
)
as
file
:
frontier_sol
.
save
(
file
,
only_macs
=
True
)
# Save min steps
...
...
@@ -354,8 +362,9 @@ def find_macs(mcla,
# Stop when limitation is reached
if
i
+
1
>=
limit
:
# EXIT
LOGGER
.
info
(
"%s:: Reaching the limitation of the number of solutions!"
,
final_prop
)
LOGGER
.
info
(
"%s:: Reaching the limitation of the number of solutions!"
,
final_prop
)
return
LOGGER
.
info
(
"%s:: STOP the search! No more MAC."
,
final_prop
)
...
...
@@ -408,16 +417,16 @@ def find_mac(mcla,
# Save MAC and timings
LOGGER
.
debug
(
"%s:: Save MAC and timings..."
,
final_prop
)
with
open
(
mac_complete_file
,
'a'
)
as
file
:
with
open
(
mac_complete_file
,
"a"
)
as
file
:
frontier_sol
.
save
(
file
)
# Save MAC (in alphabetic order...)
LOGGER
.
debug
(
"%s:: Save next MAC: %s"
,
final_prop
)
with
open
(
mac_file
,
'a'
)
as
file
:
with
open
(
mac_file
,
"a"
)
as
file
:
frontier_sol
.
save
(
file
,
only_macs
=
True
)
# Save min steps
min_step
=
mcla
.
unfolder
.
get_current_step
()
-
1
# Magic number !
min_step
=
mcla
.
unfolder
.
get_current_step
()
-
1
# Magic number !
# LOGGER.debug("%s:: Save minimal steps: %s", final_prop, min_step)
# with open(mac_step_file, 'a') as file:
# file.write(str(min_step)+'\n')
...
...
@@ -447,10 +456,11 @@ def detect_model_type(mclanalyser, filepath):
:rtype: <func>
"""
build_func
=
{
".bcx"
:
mclanalyser
.
build_from_chart_file
,
".cal"
:
mclanalyser
.
build_from_cadlang
,
".xml"
:
mclanalyser
.
build_from_pid_file
,
}
build_func
=
{
".bcx"
:
mclanalyser
.
build_from_chart_file
,
".cal"
:
mclanalyser
.
build_from_cadlang
,
".xml"
:
mclanalyser
.
build_from_pid_file
,
}
_
,
extension
=
os
.
path
.
splitext
(
filepath
)
LOGGER
.
debug
(
"Found %s extension: %s"
,
extension
,
filepath
)
...
...
@@ -462,7 +472,7 @@ def detect_model_type(mclanalyser, filepath):
return
build_func
[
extension
]
#def main(chart_file, mac_file, mac_step_file, mac_complete_file, mac_strong_file,
#
def main(chart_file, mac_file, mac_step_file, mac_complete_file, mac_strong_file,
# steps, final_prop, start_prop, inv_prop, all_macs):
#
# LOGGER.debug("Params: start: {}, inv: {}, final: {}".format(start_prop,
...
...
@@ -579,14 +589,13 @@ def compute_combinations(final_properties):
all other elements.
"""
negated_places
=
'
and not
'
.
join
(
final_properties
-
data
)
negated_places
=
"
and not
"
.
join
(
final_properties
-
data
)
return
"{}{}{}"
.
format
(
'
and
'
.
join
(
data
),
'
and not
'
if
negated_places
!=
''
else
''
,
negated_places
"
and
"
.
join
(
data
),
"
and not
"
if
negated_places
!=
""
else
""
,
negated_places
,
)
all_combinations
=
list
()
for
i
in
range
(
1
,
len
(
final_properties
)
+
1
):
...
...
@@ -611,19 +620,19 @@ def solutions_search(params):
(per logical formula on each line).
"""
# No input file
if
params
[
'
final_prop
'
]:
if
params
[
"
final_prop
"
]:
compute_macs
(
params
)
else
:
# Multiple properties in input file
# => multiprocessing: 1 process for each property
with
open
(
params
[
'
input_file
'
],
'r'
)
as
f_d
:
g
=
(
line
.
rstrip
(
'
\n
'
)
for
line
in
f_d
)
with
open
(
params
[
"
input_file
"
],
"r"
)
as
f_d
:
g
=
(
line
.
rstrip
(
"
\n
"
)
for
line
in
f_d
)
final_properties
=
[
prop
for
prop
in
g
if
prop
!=
''
]
final_properties
=
[
prop
for
prop
in
g
if
prop
!=
""
]
if
params
[
'
combinations
'
]:
if
params
[
"
combinations
"
]:
# If input_file is set, we can compute all combinations of
# final_properties. default: False
final_properties
=
compute_combinations
(
final_properties
)
...
...
@@ -647,7 +656,7 @@ def solutions_search(params):
def
update_params
(
prop
):
"""Shallow copy of parameters and update final_prop for a new run"""
new_params
=
params
.
copy
()
new_params
[
'
final_prop
'
]
=
prop
new_params
[
"
final_prop
"
]
=
prop
return
new_params
# Fix number of processes
...
...
@@ -657,10 +666,10 @@ def solutions_search(params):
with
ProcessPoolExecutor
(
max_workers
=
mp
.
cpu_count
())
as
executor
:
futures_and_output
=
{
executor
.
submit
(
compute_macs
,
update_params
(
job_property
)
):
job_property
\
for
job_property
in
final_properties
}
# Job name
futures_and_output
=
{
executor
.
submit
(
compute_macs
,
update_params
(
job_property
)
):
job_property
for
job_property
in
final_properties
}
# Job name
nb_errors
=
0
nb_done
=
0
...
...
@@ -671,9 +680,9 @@ def solutions_search(params):
# On affiche les résultats si les futures en contiennent.
# Si elles contiennent une exception, on affiche l'exception.
if
future
.
exception
()
is
not
None
:
LOGGER
.
error
(
"%s generated an exception:
\n
%s"
,
job_name
,
future
.
exception
()
)
LOGGER
.
error
(
"%s generated an exception:
\n
%s"
,
job_name
,
future
.
exception
()
)
nb_errors
+=
1
else
:
# The end
...
...
@@ -697,14 +706,12 @@ def compute_macs(params):
sys
.
setrecursionlimit
(
10000
)
# QUERY PARAMETERS
model_filename
=
os
.
path
.
basename
(
os
.
path
.
splitext
(
params
[
'
chart_file
'
])[
0
])
model_filename
=
os
.
path
.
basename
(
os
.
path
.
splitext
(
params
[
"
chart_file
"
])[
0
])
# FILES
# Add trailing '/' if not present
output
=
params
[
'output'
]
if
params
[
'output'
][
-
1
]
==
'/'
\
else
params
[
'output'
]
+
'/'
mac_file_prefix
=
output
+
model_filename
+
\
'_'
+
params
[
'final_prop'
]
+
'_mac'
output
=
params
[
"output"
]
if
params
[
"output"
][
-
1
]
==
"/"
else
params
[
"output"
]
+
"/"
mac_file_prefix
=
output
+
model_filename
+
"_"
+
params
[
"final_prop"
]
+
"_mac"
# mac_file
mac_file
=
mac_file_prefix
+
".txt"
# mac_step_file
...
...
@@ -721,7 +728,7 @@ def compute_macs(params):
except
OSError
:
pass
if
not
params
[
'
continue
'
]:
if
not
params
[
"
continue
"
]:
# Reset previous working files
# PS: the reload is done in search_entry_point() function
remove_file
(
mac_file
)
...
...
@@ -731,16 +738,21 @@ def compute_macs(params):
# MAC research
search_entry_point
(
params
[
'chart_file'
],
# chart_file
mac_file
,
# mac_file
mac_step_file
,
# mac_step_file
mac_complete_file
,
# mac_complete_file
mac_strong_file
,
# mac_strong_file
params
[
'steps'
],
params
[
'final_prop'
],
params
[
'start_prop'
],
params
[
'inv_prop'
],
params
[
'all_macs'
],
params
[
'continue'
],
params
[
'limit'
],
params
[
"chart_file"
],
# chart_file
mac_file
,
# mac_file
mac_step_file
,
# mac_step_file
mac_complete_file
,
# mac_complete_file
mac_strong_file
,
# mac_strong_file
params
[
"steps"
],
params
[
"final_prop"
],
params
[
"start_prop"
],
params
[
"inv_prop"
],
params
[
"all_macs"
],
params
[
"continue"
],
params
[
"limit"
],
)
def
read_mac_file
(
file
):
"""Return a list a fontier places already found in mac file
...
...
@@ -755,5 +767,5 @@ def read_mac_file(file):
:rtype: <set>
"""
with
open
(
file
,
'r'
)
as
f_d
:
return
{
tuple
(
line
.
rstrip
(
'
\n
'
).
split
(
' '
))
for
line
in
f_d
}
with
open
(
file
,
"r"
)
as
f_d
:
return
{
tuple
(
line
.
rstrip
(
"
\n
"
).
split
(
" "
))
for
line
in
f_d
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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