Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
abc
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
abc
Commits
94d35a25
Commit
94d35a25
authored
Jan 24, 2012
by
Alan Mishchenko
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Variable timeframe abstraction.
parent
f8e933c7
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
86 additions
and
16 deletions
+86
-16
abcexe.dsp
+2
-2
abclib.dsp
+2
-2
src/aig/gia/giaAbsVta.c
+0
-0
src/base/abci/abc.c
+2
-2
src/sat/bsat/satSolver2.c
+80
-10
No files found.
abcexe.dsp
View file @
94d35a25
...
@@ -42,7 +42,7 @@ RSC=rc.exe
...
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "C:/_projects/abc
_niklas/
" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /FR /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "C:/_projects/abc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
BSC32=bscmake.exe
...
@@ -66,7 +66,7 @@ LINK32=link.exe
...
@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "C:/_projects/abc
_niklas/
" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "C:/_projects/abc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
BSC32=bscmake.exe
...
...
abclib.dsp
View file @
94d35a25
...
@@ -41,7 +41,7 @@ RSC=rc.exe
...
@@ -41,7 +41,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "ReleaseLib"
# PROP Intermediate_Dir "ReleaseLib"
# PROP Target_Dir ""
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "C:/_projects/abc
_niklas/
" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /FR /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "C:/_projects/abc" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
BSC32=bscmake.exe
...
@@ -64,7 +64,7 @@ LIB32=link.exe -lib
...
@@ -64,7 +64,7 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "DebugLib"
# PROP Intermediate_Dir "DebugLib"
# PROP Target_Dir ""
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "C:/_projects/abc
_niklas/
" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "C:/_projects/abc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
BSC32=bscmake.exe
...
...
src/aig/gia/giaAbsVta.c
View file @
94d35a25
This diff is collapsed.
Click to expand it.
src/base/abci/abc.c
View file @
94d35a25
...
@@ -26404,7 +26404,7 @@ usage:
...
@@ -26404,7 +26404,7 @@ usage:
***********************************************************************/
***********************************************************************/
int
Abc_CommandAbc9Vta
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
int
Abc_CommandAbc9Vta
(
Abc_Frame_t
*
pAbc
,
int
argc
,
char
**
argv
)
{
{
Gia_ParVta_t
Pars
,
Pars2
,
*
pPars
=
&
Pars
;
Gia_ParVta_t
Pars
,
*
pPars
=
&
Pars
;
int
c
;
int
c
;
Gia_VtaSetDefaultParams
(
pPars
);
Gia_VtaSetDefaultParams
(
pPars
);
Extra_UtilGetoptReset
();
Extra_UtilGetoptReset
();
...
@@ -26483,7 +26483,7 @@ int Abc_CommandAbc9Vta( Abc_Frame_t * pAbc, int argc, char ** argv )
...
@@ -26483,7 +26483,7 @@ int Abc_CommandAbc9Vta( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print
(
1
,
"The network is more than one PO (run
\"
orpos
\"
).
\n
"
);
Abc_Print
(
1
,
"The network is more than one PO (run
\"
orpos
\"
).
\n
"
);
return
0
;
return
0
;
}
}
if
(
pPars
->
nFramesMax
>
0
)
if
(
pPars
->
nFramesMax
<
0
)
{
{
Abc_Print
(
1
,
"The number of starting frames should be a positive integer.
\n
"
);
Abc_Print
(
1
,
"The number of starting frames should be a positive integer.
\n
"
);
return
0
;
return
0
;
...
...
src/sat/bsat/satSolver2.c
View file @
94d35a25
...
@@ -141,7 +141,7 @@ static inline satset* clause_read (sat_solver2* s, cla h) { return (h & 1
...
@@ -141,7 +141,7 @@ static inline satset* clause_read (sat_solver2* s, cla h) { return (h & 1
static
inline
cla
clause_handle
(
sat_solver2
*
s
,
satset
*
c
)
{
return
c
->
learnt
?
(
satset_handle
(
&
s
->
learnts
,
c
)
<<
1
)
|
1
:
satset_handle
(
&
s
->
clauses
,
c
)
<<
1
;
}
static
inline
cla
clause_handle
(
sat_solver2
*
s
,
satset
*
c
)
{
return
c
->
learnt
?
(
satset_handle
(
&
s
->
learnts
,
c
)
<<
1
)
|
1
:
satset_handle
(
&
s
->
clauses
,
c
)
<<
1
;
}
static
inline
int
clause_check
(
sat_solver2
*
s
,
satset
*
c
)
{
return
c
->
learnt
?
satset_check
(
&
s
->
learnts
,
c
)
:
satset_check
(
&
s
->
clauses
,
c
);
}
static
inline
int
clause_check
(
sat_solver2
*
s
,
satset
*
c
)
{
return
c
->
learnt
?
satset_check
(
&
s
->
learnts
,
c
)
:
satset_check
(
&
s
->
clauses
,
c
);
}
static
inline
int
clause_proofid
(
sat_solver2
*
s
,
satset
*
c
,
int
partA
)
{
return
c
->
learnt
?
(
veci_begin
(
&
s
->
claProofs
)[
c
->
Id
]
<<
2
)
|
(
partA
<<
1
)
:
(
satset_handle
(
&
s
->
clauses
,
c
)
<<
2
)
|
(
partA
<<
1
)
|
1
;
}
static
inline
int
clause_proofid
(
sat_solver2
*
s
,
satset
*
c
,
int
partA
)
{
return
c
->
learnt
?
(
veci_begin
(
&
s
->
claProofs
)[
c
->
Id
]
<<
2
)
|
(
partA
<<
1
)
:
(
satset_handle
(
&
s
->
clauses
,
c
)
<<
2
)
|
(
partA
<<
1
)
|
1
;
}
static
inline
int
clause_is_used
(
sat_solver2
*
s
,
cla
h
)
{
return
(
h
&
1
)
?
(
h
>>
1
)
<
s
->
hLearntPivot
:
(
h
>>
1
)
<
s
->
hClausePivot
;
}
static
inline
int
clause_is_used
(
sat_solver2
*
s
,
cla
h
)
{
return
(
h
&
1
)
?
(
(
h
>>
1
)
<
s
->
hLearntPivot
)
:
((
h
>>
1
)
<
s
->
hClausePivot
);
}
//static inline int var_reason (sat_solver2* s, int v) { return (s->reasons[v]&1) ? 0 : s->reasons[v] >> 1; }
//static inline int var_reason (sat_solver2* s, int v) { return (s->reasons[v]&1) ? 0 : s->reasons[v] >> 1; }
//static inline int lit_reason (sat_solver2* s, int l) { return (s->reasons[lit_var(l)&1]) ? 0 : s->reasons[lit_var(l)] >> 1; }
//static inline int lit_reason (sat_solver2* s, int l) { return (s->reasons[lit_var(l)&1]) ? 0 : s->reasons[lit_var(l)] >> 1; }
...
@@ -150,8 +150,8 @@ static inline int clause_is_used(sat_solver2* s, cla h) { return (h & 1
...
@@ -150,8 +150,8 @@ static inline int clause_is_used(sat_solver2* s, cla h) { return (h & 1
static
inline
int
var_reason
(
sat_solver2
*
s
,
int
v
)
{
return
s
->
reasons
[
v
];
}
static
inline
int
var_reason
(
sat_solver2
*
s
,
int
v
)
{
return
s
->
reasons
[
v
];
}
static
inline
int
lit_reason
(
sat_solver2
*
s
,
int
l
)
{
return
s
->
reasons
[
lit_var
(
l
)];
}
static
inline
int
lit_reason
(
sat_solver2
*
s
,
int
l
)
{
return
s
->
reasons
[
lit_var
(
l
)];
}
static
inline
satset
*
var_unit_clause
(
sat_solver2
*
s
,
int
v
)
{
return
clause_read
(
s
,
s
->
units
[
v
]);
}
static
inline
satset
*
var_unit_clause
(
sat_solver2
*
s
,
int
v
)
{
return
clause_read
(
s
,
s
->
units
[
v
]);
}
//
static inline void var_set_unit_clause(sat_solver2* s, int v, cla i){ assert(v >= 0 && v < s->size && !s->units[v]); s->units[v] = i; s->nUnits++; }
static
inline
void
var_set_unit_clause
(
sat_solver2
*
s
,
int
v
,
cla
i
){
assert
(
v
>=
0
&&
v
<
s
->
size
&&
!
s
->
units
[
v
]);
s
->
units
[
v
]
=
i
;
s
->
nUnits
++
;
}
static
inline
void
var_set_unit_clause
(
sat_solver2
*
s
,
int
v
,
cla
i
){
assert
(
v
>=
0
&&
v
<
s
->
size
);
s
->
units
[
v
]
=
i
;
s
->
nUnits
++
;
}
//
static inline void var_set_unit_clause(sat_solver2* s, int v, cla i){ assert(v >= 0 && v < s->size); s->units[v] = i; s->nUnits++; }
// these two only work after creating a clause before the solver is called
// these two only work after creating a clause before the solver is called
int
clause_is_partA
(
sat_solver2
*
s
,
int
h
)
{
return
clause_read
(
s
,
h
)
->
partA
;
}
int
clause_is_partA
(
sat_solver2
*
s
,
int
h
)
{
return
clause_read
(
s
,
h
)
->
partA
;
}
...
@@ -501,8 +501,12 @@ static void solver2_canceluntil(sat_solver2* s, int level) {
...
@@ -501,8 +501,12 @@ static void solver2_canceluntil(sat_solver2* s, int level) {
for
(
c
=
s
->
qtail
-
1
;
c
>=
bound
;
c
--
)
for
(
c
=
s
->
qtail
-
1
;
c
>=
bound
;
c
--
)
{
{
x
=
lit_var
(
trail
[
c
]);
x
=
lit_var
(
trail
[
c
]);
var_set_value
(
s
,
x
,
varX
);
s
->
reasons
[
x
]
=
0
;
s
->
reasons
[
x
]
=
0
;
// if ( s->units[x] == 0 || var_level(s, x) > 0 )
{
var_set_value
(
s
,
x
,
varX
);
s
->
units
[
x
]
=
0
;
// temporary?
}
if
(
c
<
lastLev
)
if
(
c
<
lastLev
)
var_set_polar
(
s
,
x
,
!
lit_sign
(
trail
[
c
]));
var_set_polar
(
s
,
x
,
!
lit_sign
(
trail
[
c
]));
}
}
...
@@ -1551,7 +1555,7 @@ void sat_solver2_rollback( sat_solver2* s )
...
@@ -1551,7 +1555,7 @@ void sat_solver2_rollback( sat_solver2* s )
{
{
int
i
,
k
,
j
;
int
i
,
k
,
j
;
assert
(
s
->
hClausePivot
>=
1
&&
s
->
hClausePivot
<=
veci_size
(
&
s
->
clauses
)
);
assert
(
s
->
hClausePivot
>=
1
&&
s
->
hClausePivot
<=
veci_size
(
&
s
->
clauses
)
);
assert
(
s
->
hLearntPivot
>=
1
&&
s
->
hLearntPivot
<=
veci_size
(
&
s
->
clause
s
)
);
assert
(
s
->
hLearntPivot
>=
1
&&
s
->
hLearntPivot
<=
veci_size
(
&
s
->
learnt
s
)
);
assert
(
s
->
iVarPivot
>=
0
&&
s
->
iVarPivot
<=
s
->
size
);
assert
(
s
->
iVarPivot
>=
0
&&
s
->
iVarPivot
<=
s
->
size
);
veci_resize
(
&
s
->
order
,
0
);
veci_resize
(
&
s
->
order
,
0
);
if
(
s
->
hClausePivot
>
1
||
s
->
hLearntPivot
>
1
)
if
(
s
->
hClausePivot
>
1
||
s
->
hLearntPivot
>
1
)
...
@@ -1581,18 +1585,24 @@ void sat_solver2_rollback( sat_solver2* s )
...
@@ -1581,18 +1585,24 @@ void sat_solver2_rollback( sat_solver2* s )
s
->
units
[
i
]
=
0
;
s
->
units
[
i
]
=
0
;
}
}
// reset
// reset
if
(
s
->
hClausePivot
<
veci_size
(
&
s
->
clauses
)
)
{
satset
*
first
=
satset_read
(
&
s
->
clauses
,
s
->
hClausePivot
);
s
->
stats
.
clauses
=
first
->
Id
;
veci_resize
(
&
s
->
clauses
,
s
->
hClausePivot
);
}
if
(
s
->
hLearntPivot
<
veci_size
(
&
s
->
learnts
)
)
if
(
s
->
hLearntPivot
<
veci_size
(
&
s
->
learnts
)
)
{
{
satset
*
first
=
satset_read
(
&
s
->
learnts
,
s
->
hLearntPivot
);
satset
*
first
=
satset_read
(
&
s
->
learnts
,
s
->
hLearntPivot
);
veci_resize
(
&
s
->
claActs
,
first
->
Id
);
veci_resize
(
&
s
->
claActs
,
first
->
Id
+
1
);
if
(
s
->
fProofLogging
)
{
if
(
s
->
fProofLogging
)
{
veci_resize
(
&
s
->
claProofs
,
first
->
Id
);
veci_resize
(
&
s
->
claProofs
,
first
->
Id
+
1
);
Sat_ProofReduce
(
s
);
Sat_ProofReduce
(
s
);
}
}
}
s
->
stats
.
learnts
=
first
->
Id
;
veci_resize
(
&
s
->
clauses
,
s
->
hClausePivot
);
veci_resize
(
&
s
->
learnts
,
s
->
hLearntPivot
);
veci_resize
(
&
s
->
learnts
,
s
->
hLearntPivot
);
for
(
i
=
s
->
iVarPivot
;
i
<
s
->
size
*
2
;
i
++
)
}
for
(
i
=
2
*
s
->
iVarPivot
;
i
<
2
*
s
->
size
;
i
++
)
s
->
wlists
[
i
].
size
=
0
;
s
->
wlists
[
i
].
size
=
0
;
s
->
size
=
s
->
iVarPivot
;
s
->
size
=
s
->
iVarPivot
;
// initialize other vars
// initialize other vars
...
@@ -1628,9 +1638,67 @@ void sat_solver2_rollback( sat_solver2* s )
...
@@ -1628,9 +1638,67 @@ void sat_solver2_rollback( sat_solver2* s )
s
->
stats
.
learnts
=
0
;
s
->
stats
.
learnts
=
0
;
s
->
stats
.
learnts_literals
=
0
;
s
->
stats
.
learnts_literals
=
0
;
s
->
stats
.
tot_literals
=
0
;
s
->
stats
.
tot_literals
=
0
;
// initialize clause pointers
s
->
hClausePivot
=
1
;
s
->
hLearntPivot
=
1
;
s
->
hLearntLast
=
-
1
;
// the last learnt clause
}
}
}
}
// find the clause in the watcher lists
int
sat_solver2_find_clause
(
sat_solver2
*
s
,
int
Hand
,
int
fVerbose
)
{
int
i
,
k
,
Found
=
0
;
if
(
Hand
>=
s
->
clauses
.
size
)
return
1
;
for
(
i
=
0
;
i
<
s
->
size
*
2
;
i
++
)
{
cla
*
pArray
=
veci_begin
(
&
s
->
wlists
[
i
]);
for
(
k
=
0
;
k
<
veci_size
(
&
s
->
wlists
[
i
]);
k
++
)
if
(
(
pArray
[
k
]
>>
1
)
==
Hand
)
{
if
(
fVerbose
)
printf
(
"Clause found in list %d.
\n
"
,
k
);
Found
=
1
;
break
;
}
}
if
(
Found
==
0
)
{
if
(
fVerbose
)
printf
(
"Clause with hand %d is not found.
\n
"
,
Hand
);
}
return
Found
;
}
// verify that all clauses are satisfied
void
sat_solver2_verify
(
sat_solver2
*
s
)
{
satset
*
c
;
int
i
,
k
,
v
,
Counter
=
0
;
satset_foreach_entry
(
&
s
->
clauses
,
c
,
i
,
1
)
{
for
(
k
=
0
;
k
<
(
int
)
c
->
nEnts
;
k
++
)
{
v
=
lit_var
(
c
->
pEnts
[
k
]);
if
(
sat_solver2_var_value
(
s
,
v
)
^
lit_sign
(
c
->
pEnts
[
k
])
)
break
;
}
if
(
k
==
(
int
)
c
->
nEnts
)
{
printf
(
"Clause %d is not satisfied. "
,
c
->
Id
);
satset_print
(
c
);
sat_solver2_find_clause
(
s
,
satset_handle
(
&
s
->
clauses
,
c
),
1
);
Counter
++
;
}
}
if
(
Counter
==
0
)
printf
(
"Verification passed.
\n
"
);
else
printf
(
"Verification failed!
\n
"
);
}
int
sat_solver2_solve
(
sat_solver2
*
s
,
lit
*
begin
,
lit
*
end
,
ABC_INT64_T
nConfLimit
,
ABC_INT64_T
nInsLimit
,
ABC_INT64_T
nConfLimitGlobal
,
ABC_INT64_T
nInsLimitGlobal
)
int
sat_solver2_solve
(
sat_solver2
*
s
,
lit
*
begin
,
lit
*
end
,
ABC_INT64_T
nConfLimit
,
ABC_INT64_T
nInsLimit
,
ABC_INT64_T
nConfLimitGlobal
,
ABC_INT64_T
nInsLimitGlobal
)
{
{
int
restart_iter
=
0
;
int
restart_iter
=
0
;
...
@@ -1798,6 +1866,8 @@ int sat_solver2_solve(sat_solver2* s, lit* begin, lit* end, ABC_INT64_T nConfLim
...
@@ -1798,6 +1866,8 @@ int sat_solver2_solve(sat_solver2* s, lit* begin, lit* end, ABC_INT64_T nConfLim
printf
(
"==============================================================================
\n
"
);
printf
(
"==============================================================================
\n
"
);
solver2_canceluntil
(
s
,
0
);
solver2_canceluntil
(
s
,
0
);
if
(
status
==
l_True
)
sat_solver2_verify
(
s
);
return
status
;
return
status
;
}
}
...
...
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