Fixing minor portability issues
This commit is contained in:
@@ -212,7 +212,7 @@
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
:- module(extlists, [open_end_memberchk/2, open_end_add/3, open_end_add_unique/3, open_end_close_end/2]).
|
||||
:- ensure_loaded(library(lists)).
|
||||
:- use_module(library(lists)).
|
||||
|
||||
open_end_memberchk(_A, []):-!, fail.
|
||||
open_end_memberchk(A, L-E):-
|
||||
|
@@ -435,14 +435,14 @@ flag_validate_directory(Value):-
|
||||
flag_validate_directory(Value):-
|
||||
atomic(Value),
|
||||
% fixme : why not inform the user???
|
||||
catch((not(file_exists(Value)), make_directory(Value)), _, fail).
|
||||
catch((\+ file_exists(Value), make_directory(Value)), _, fail).
|
||||
|
||||
flag_validate_file.
|
||||
flag_validate_file(Value):-
|
||||
catch(file_exists(Value), _, fail), file_property(Value, type(regular)), !.
|
||||
flag_validate_file(Value):-
|
||||
atomic(Value),
|
||||
catch((not(file_exists(Value)), tell(Value)), _, fail),
|
||||
catch((\+ file_exists(Value), tell(Value)), _, fail),
|
||||
told,
|
||||
delete_file(Value).
|
||||
|
||||
|
@@ -276,7 +276,7 @@
|
||||
hash_table_display/3,
|
||||
problog_key_to_tuple/2]).
|
||||
|
||||
:- ensure_loaded(library(lists)).
|
||||
:- use_module(library(lists)).
|
||||
%
|
||||
% General use predicates
|
||||
%
|
||||
@@ -705,7 +705,7 @@ hash_table_get_elements(RevArray, RevSize, RevSize, Tupples):-
|
||||
hash_table_get_elements(_RevArray, RevSize, RevSize, []).
|
||||
|
||||
hash_table_get_chains(Array, Size, Chains):-
|
||||
((array_element(Array, Size, ChainID), not(ChainID == 0)) ->
|
||||
((array_element(Array, Size, ChainID), ChainID \== 0) ->
|
||||
(integer(ChainID) ->
|
||||
get_array_name(ChainID, ChainName)
|
||||
;
|
||||
|
@@ -206,9 +206,9 @@
|
||||
|
||||
:- module(mc_DNF_sampling, [problog_dnf_sampling/3]).
|
||||
|
||||
:- ensure_loaded(library(lists)).
|
||||
:- use_module(library(lists)).
|
||||
|
||||
:- ensure_loaded(variables).
|
||||
:- use_module(variables).
|
||||
:- use_module(sampling, _, [problog_random/1,
|
||||
problog_convergence_check/6]).
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
|
||||
:- use_module(os, _, [convert_filename_to_working_path/2]).
|
||||
|
||||
:- ensure_loaded(hash_table).
|
||||
:- use_module(hash_table).
|
||||
|
||||
:- problog_define_flag(search_method, problog_flag_validate_in_list([linear, binary]), 'search method for picking proof', binary, monte_carlo_sampling_dnf).
|
||||
:- problog_define_flag(represent_world, problog_flag_validate_in_list([list, record, array, hash_table]), 'structure that represents sampled world', array, monte_carlo_sampling_dnf).
|
||||
|
@@ -216,7 +216,7 @@
|
||||
|
||||
|
||||
% load library modules
|
||||
:- ensure_loaded(library(system)).
|
||||
:- use_module(library(system)).
|
||||
|
||||
% load our own modules
|
||||
:- use_module(gflags, _, [flag_get/2]).
|
||||
@@ -225,7 +225,7 @@
|
||||
|
||||
set_problog_path(Path):-
|
||||
retractall(problog_path(_)),
|
||||
assert(problog_path(Path)).
|
||||
assertz(problog_path(Path)).
|
||||
|
||||
convert_filename_to_working_path(File_Name, Path):-
|
||||
flag_get(dir, Dir),
|
||||
|
@@ -225,11 +225,11 @@
|
||||
problog_help/0]).
|
||||
|
||||
% load library modules
|
||||
:- ensure_loaded(library(lists)).
|
||||
:- use_module(library(lists)).
|
||||
|
||||
% load our own modules
|
||||
:- ensure_loaded(flags).
|
||||
:- ensure_loaded(variables).
|
||||
:- use_module(flags).
|
||||
:- use_module(variables).
|
||||
|
||||
|
||||
% size, line_char, line_char_bold
|
||||
|
@@ -211,10 +211,10 @@
|
||||
|
||||
|
||||
% load library modules
|
||||
:- ensure_loaded(library(system)).
|
||||
:- use_module(library(system)).
|
||||
|
||||
% load our own modules
|
||||
:- ensure_loaded(flags).
|
||||
:- use_module(flags).
|
||||
|
||||
:- initialization(problog_define_flag(verbosity_learning, problog_flag_validate_0to5,'How much output shall be given (0=nothing,5=all)',5, learning_general)).
|
||||
|
||||
|
@@ -212,7 +212,7 @@
|
||||
|
||||
:- use_module(os, _, [convert_filename_to_working_path/2]).
|
||||
|
||||
:- ensure_loaded(library(random)).
|
||||
:- use_module(library(random)).
|
||||
|
||||
:- problog_define_flag(mc_batchsize, problog_flag_validate_posint, 'number of samples before update in montecarlo', 1000, monte_carlo_sampling).
|
||||
|
||||
|
@@ -233,7 +233,7 @@
|
||||
problog_tabling_get_negated_from_id/2,
|
||||
op(1150, fx, problog_table)]).
|
||||
|
||||
:- ensure_loaded(library(lists)).
|
||||
:- use_module(library(lists)).
|
||||
|
||||
:- use_module(extlists, _, [open_end_memberchk/2,
|
||||
open_end_add/3,
|
||||
@@ -248,8 +248,8 @@
|
||||
empty_ptree/1]).
|
||||
|
||||
:- op( 1150, fx, problog_table ).
|
||||
:- meta_predicate problog_table(:).
|
||||
:- meta_predicate problog_neg(:).
|
||||
:- meta_predicate(problog_table(0)).
|
||||
:- meta_predicate(problog_neg(0)).
|
||||
:- dynamic problog_tabled/1, has_synonyms/0, problog_tabling_retain/1.
|
||||
:- problog_define_flag(max_depth, problog_flag_validate_integer, 'maximum proof depth', -1).
|
||||
:- problog_define_flag(retain_tables, problog_flag_validate_boolean, 'retain tables after query', false).
|
||||
@@ -277,7 +277,7 @@ clear_tabling:-
|
||||
clear_tabling.
|
||||
|
||||
retain_tabling:-
|
||||
forall(problog_chktabled(_, Trie), assert(problog_tabling_retain(Trie))).
|
||||
forall(problog_chktabled(_, Trie), assertz(problog_tabling_retain(Trie))).
|
||||
|
||||
clear_retained_tables:-
|
||||
forall(problog_tabling_retain(Trie), delete_ptree(Trie)),
|
||||
@@ -311,7 +311,7 @@ problog_table((P1, P2), M) :-
|
||||
problog_table(Name/Arity, Module) :-
|
||||
makeargs(Arity, Args),
|
||||
Head =.. [Name|Args],
|
||||
not(predicate_property(Module:Head, dynamic)), !,
|
||||
\+ predicate_property(Module:Head, dynamic), !,
|
||||
throw(error('problog_table: Problog tabling currently requires the predicate to be declared dynamic and compiles it to static.')).
|
||||
problog_table(Name/Arity, Module) :-
|
||||
makeargs(Arity, Args),
|
||||
@@ -322,7 +322,7 @@ problog_table(Name/Arity, Module) :-
|
||||
|
||||
% Monte carlo tabling
|
||||
table(Module:MCName/Arity),
|
||||
assert(problog_tabled(Module:Name/Arity)),
|
||||
assertz(problog_tabled(Module:Name/Arity)),
|
||||
|
||||
findall(_,(
|
||||
OriginalPred =.. [OriginalName|Args],
|
||||
@@ -334,7 +334,7 @@ problog_table(Name/Arity, Module) :-
|
||||
OriginalPred =.. [OriginalName|Args],
|
||||
MCPred =.. [MCName|Args],
|
||||
ExactPred =.. [ExactName|Args],
|
||||
assert(Module:(
|
||||
assertz(Module:(
|
||||
Head:-
|
||||
(problog:problog_control(check, exact) ->
|
||||
ExactPred
|
||||
@@ -361,7 +361,7 @@ problog_table(Name/Arity, Module) :-
|
||||
Finished
|
||||
),
|
||||
b_getval(problog_current_proof, IDs),
|
||||
not(open_end_memberchk(not(t(Hash)), IDs)),
|
||||
\+ open_end_memberchk(not(t(Hash)), IDs),
|
||||
open_end_add_unique(t(Hash), IDs, NIDs),
|
||||
b_setval(problog_current_proof, NIDs)
|
||||
;
|
||||
@@ -413,7 +413,7 @@ problog_table(Name/Arity, Module) :-
|
||||
delete_ptree(SuspTrie)
|
||||
),
|
||||
b_setval(CurrentControlTrie, OCurTrie),
|
||||
not(open_end_memberchk(not(t(Hash)), OIDs)),
|
||||
\+ open_end_memberchk(not(t(Hash)), OIDs),
|
||||
open_end_add_unique(t(Hash), OIDs, NOIDs),
|
||||
b_setval(problog_current_proof, NOIDs)
|
||||
)
|
||||
@@ -435,8 +435,8 @@ problog_abolish_table(M:P/A):-
|
||||
problog_neg(M:G):-
|
||||
problog:problog_control(check, exact),
|
||||
functor(G, Name, Arity),
|
||||
not(problog_tabled(M:Name/Arity)),
|
||||
not(problog:problog_predicate(Name, Arity)),
|
||||
\+ problog_tabled(M:Name/Arity),
|
||||
\+ problog:problog_predicate(Name, Arity),
|
||||
throw(problog_neg_error('Error: goal must be dynamic and tabled', M:G)).
|
||||
problog_neg(M:G):-
|
||||
% exact inference
|
||||
@@ -446,20 +446,20 @@ problog_neg(M:G):-
|
||||
M:G,
|
||||
b_getval(problog_current_proof, L),
|
||||
open_end_close_end(L, [Trie]),
|
||||
not(open_end_memberchk(Trie, IDs)),
|
||||
\+ open_end_memberchk(Trie, IDs),
|
||||
open_end_add_unique(not(Trie), IDs, NIDs),
|
||||
b_setval(problog_current_proof, NIDs).
|
||||
problog_neg(M:G):-
|
||||
% monte carlo sampling
|
||||
problog:problog_control(check, mc),
|
||||
not(M:G).
|
||||
\+ M:G.
|
||||
|
||||
% This predicate assigns a synonym for negation that means: NotName = problog_neg(Name)
|
||||
problog_tabling_negated_synonym(Name, NotName):-
|
||||
recorded(problog_table_synonyms, negated(Name, NotName), _), !.
|
||||
problog_tabling_negated_synonym(Name, NotName):-
|
||||
retractall(has_synonyms),
|
||||
assert(has_synonyms),
|
||||
assertz(has_synonyms),
|
||||
recordz(problog_table_synonyms, negated(Name, NotName), _).
|
||||
|
||||
problog_tabling_get_negated_from_pred(Pred, Ref):-
|
||||
|
@@ -225,7 +225,7 @@ timer_start(Name) :-
|
||||
throw(timer_already_started(timer_start(Name)));
|
||||
|
||||
statistics(walltime,[StartTime,_]),
|
||||
assert(timer(Name,StartTime))
|
||||
assertz(timer(Name,StartTime))
|
||||
).
|
||||
|
||||
timer_stop(Name,Duration) :-
|
||||
@@ -244,7 +244,7 @@ timer_pause(Name) :-
|
||||
->
|
||||
statistics(walltime,[StopTime,_]),
|
||||
Duration is StopTime-StartTime,
|
||||
assert(timer_paused(Name,Duration));
|
||||
assertz(timer_paused(Name,Duration));
|
||||
|
||||
throw(timer_not_started(timer_pause(Name)))
|
||||
).
|
||||
@@ -255,7 +255,7 @@ timer_pause(Name, Duration) :-
|
||||
->
|
||||
statistics(walltime,[StopTime,_]),
|
||||
Duration is StopTime-StartTime,
|
||||
assert(timer_paused(Name,Duration));
|
||||
assertz(timer_paused(Name,Duration));
|
||||
|
||||
throw(timer_not_started(timer_pause(Name)))
|
||||
).
|
||||
@@ -266,7 +266,7 @@ timer_resume(Name):-
|
||||
->
|
||||
statistics(walltime,[ResumeTime,_]),
|
||||
CorrectedStartTime is ResumeTime-Duration,
|
||||
assert(timer(Name,CorrectedStartTime));
|
||||
assertz(timer(Name,CorrectedStartTime));
|
||||
|
||||
throw(timer_not_paused(timer_resume(Name)))
|
||||
).
|
||||
|
@@ -245,13 +245,13 @@
|
||||
]).
|
||||
|
||||
% load library modules
|
||||
:- ensure_loaded(library(tries)).
|
||||
:- ensure_loaded(library(lists)).
|
||||
:- ensure_loaded(library(system)).
|
||||
:- ensure_loaded(library(ordsets)).
|
||||
:- use_module(library(tries)).
|
||||
:- use_module(library(lists)).
|
||||
:- use_module(library(system)).
|
||||
:- use_module(library(ordsets)).
|
||||
|
||||
% load our own modules
|
||||
:- ensure_loaded(flags).
|
||||
:- use_module(flags).
|
||||
|
||||
% switch on all tests to reduce bug searching time
|
||||
:- style_check(all).
|
||||
@@ -435,7 +435,7 @@ bdd_struct_ptree_script(Trie, FileBDD, Variables) :-
|
||||
edges_ptree(Trie, Variables),
|
||||
name_vars(Variables), % expected by output_compressed_script/1?
|
||||
length(Variables, VarCount),
|
||||
assert(c_num(1)),
|
||||
assertz(c_num(1)),
|
||||
bdd_pt(Trie, CT),
|
||||
c_num(NN),
|
||||
IntermediateSteps is NN - 1,
|
||||
@@ -643,7 +643,7 @@ bdd_ptree_script(Trie, FileBDD, FileParam) :-
|
||||
|
||||
told,
|
||||
length(Edges, VarCount),
|
||||
assert(c_num(1)),
|
||||
assertz(c_num(1)),
|
||||
bdd_pt(Trie, CT),
|
||||
c_num(NN),
|
||||
IntermediateSteps is NN - 1,
|
||||
@@ -736,12 +736,12 @@ bdd_pt(Trie, false) :-
|
||||
empty_ptree(Trie),
|
||||
!,
|
||||
retractall(c_num(_)),
|
||||
assert(c_num(2)).
|
||||
assertz(c_num(2)).
|
||||
bdd_pt(Trie, true) :-
|
||||
trie_check_entry(Trie, [true], _),
|
||||
!,
|
||||
retractall(c_num(_)),
|
||||
assert(c_num(2)).
|
||||
assertz(c_num(2)).
|
||||
|
||||
% general case: transform trie to nested tree structure for compression
|
||||
bdd_pt(Trie, CT) :-
|
||||
@@ -977,7 +977,7 @@ format_compression_script([A, B|C]) :-
|
||||
get_next_name(Name) :-
|
||||
retract(c_num(N)),
|
||||
NN is N + 1,
|
||||
assert(c_num(NN)),
|
||||
assertz(c_num(NN)),
|
||||
atomic_concat('L', N, Name).
|
||||
|
||||
% create BDD-var as fact id prefixed by x
|
||||
@@ -1030,7 +1030,7 @@ print_nested_ptree(Trie, Level, Space):-
|
||||
spacy_print(begin(t(Trie)), Level, Space),
|
||||
fail.
|
||||
print_nested_ptree(Trie, Level, Space):-
|
||||
assert(nested_ptree_printed(Trie)),
|
||||
assertz(nested_ptree_printed(Trie)),
|
||||
trie_path(Trie, Path),
|
||||
NewLevel is Level + 1,
|
||||
spacy_print(Path, NewLevel, Space),
|
||||
@@ -1117,7 +1117,7 @@ generate_BDD_from_trie(Trie, TrieInter, Stream):-
|
||||
get_next_intermediate_step(TrieInter),
|
||||
write_bdd_line(OrLineTerms, TrieInter, '+', Stream)
|
||||
),
|
||||
assert(generated_trie(Trie, TrieInter)).
|
||||
assertz(generated_trie(Trie, TrieInter)).
|
||||
|
||||
write_bdd_line([], _LineInter, _Operator, _Stream):-!.
|
||||
write_bdd_line(LineTerms, LineInter, Operator, Stream):-
|
||||
@@ -1172,13 +1172,13 @@ bddvars_to_script([H|T], Stream):-
|
||||
bddvars_to_script(T, Stream).
|
||||
|
||||
get_next_intermediate_step('L1'):-
|
||||
not(clause(next_intermediate_step(_), _)), !,
|
||||
assert(next_intermediate_step(2)).
|
||||
\+ clause(next_intermediate_step(_), _), !,
|
||||
assertz(next_intermediate_step(2)).
|
||||
get_next_intermediate_step(Inter):-
|
||||
next_intermediate_step(InterStep),
|
||||
retract(next_intermediate_step(InterStep)),
|
||||
NextInterStep is InterStep + 1,
|
||||
assert(next_intermediate_step(NextInterStep)),
|
||||
assertz(next_intermediate_step(NextInterStep)),
|
||||
atomic_concat(['L', InterStep], Inter).
|
||||
|
||||
make_bdd_var('true', 'TRUE'):-!.
|
||||
@@ -1201,9 +1201,9 @@ add_to_vars(V):-
|
||||
clause(get_used_vars(Vars, Cnt), true), !,
|
||||
retract(get_used_vars(Vars, Cnt)),
|
||||
NewCnt is Cnt + 1,
|
||||
assert(get_used_vars([V|Vars], NewCnt)).
|
||||
assertz(get_used_vars([V|Vars], NewCnt)).
|
||||
add_to_vars(V):-
|
||||
assert(get_used_vars([V], 1)).
|
||||
assertz(get_used_vars([V], 1)).
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%% depth breadth builtin support %%%%%%%%%%%%%%%%%
|
||||
@@ -1232,14 +1232,14 @@ variable_in_dbtrie(Trie, V):-
|
||||
|
||||
get_next_variable(V, depth(L, _S)):-
|
||||
member(V, L),
|
||||
not(islabel(V)).
|
||||
\+ islabel(V).
|
||||
get_next_variable(V, breadth(L, _S)):-
|
||||
member(V, L),
|
||||
not(islabel(V)).
|
||||
\+ islabel(V).
|
||||
get_next_variable(V, L):-
|
||||
member(V, L),
|
||||
not(islabel(V)),
|
||||
not(isnestedtrie(V)).
|
||||
\+ islabel(V),
|
||||
\+ isnestedtrie(V).
|
||||
|
||||
get_variable(not(V), R):-
|
||||
!, get_variable(V, R).
|
||||
@@ -1408,7 +1408,7 @@ preprocess(_, _, _, FinalEndCount, FinalEndCount).
|
||||
|
||||
make_nested_trie_base_cases(Trie, t(ID), DepthBreadthTrie, OptimizationLevel, StartCount, FinalEndCount, Ancestors):-
|
||||
trie_to_depth_breadth_trie(Trie, DepthBreadthTrie, Label, OptimizationLevel, StartCount, EndCount),
|
||||
(not(Label = t(_)) ->
|
||||
(Label \= t(_) ->
|
||||
FinalEndCount = EndCount,
|
||||
problog:problog_chktabled(ID, RTrie),!,
|
||||
get_set_trie_from_id(t(ID), Label, RTrie, Ancestors, _, Ancestors)
|
||||
@@ -1439,7 +1439,7 @@ trie_nested_to_db_trie(Trie, DepthBreadthTrie, FinalLabel, OptimizationLevel, St
|
||||
|
||||
nested_trie_to_db_trie(Trie, DepthBreadthTrie, FinalLabel, OptimizationLevel, StartCount, FinalEndCount, Module:GetTriePredicate, Ancestors, ContainsLoop, Childs, ChildsAcc):-
|
||||
trie_to_depth_breadth_trie(Trie, DepthBreadthTrie, Label, OptimizationLevel, StartCount, EndCount),
|
||||
(not(Label = t(_)) ->
|
||||
(Label \= t(_) ->
|
||||
(var(ContainsLoop) ->
|
||||
ContainsLoop = false
|
||||
;
|
||||
@@ -1933,7 +1933,7 @@ dwriteln(A):-
|
||||
|
||||
non_false([], []):-!.
|
||||
non_false([H|T], [H|NT]):-
|
||||
not(H == false),
|
||||
H \== false,
|
||||
non_false(T, NT).
|
||||
non_false([H|T], NT):-
|
||||
H == false,
|
||||
@@ -1945,11 +1945,11 @@ one_true(_, _, 'TRUE'):-!.
|
||||
|
||||
all_false(false,false,false).
|
||||
one_non_false(L, false, false, L):-
|
||||
not(L == false), !.
|
||||
L \== false, !.
|
||||
one_non_false(false, L, false, L):-
|
||||
not(L == false), !.
|
||||
L \== false, !.
|
||||
one_non_false(false, false, L, L):-
|
||||
not(L == false), !.
|
||||
L \== false, !.
|
||||
|
||||
trie_seperate(Trie, Var, TrieWith, TrieWithNeg, TrieWithOut):-
|
||||
trie_traverse(Trie, R),
|
||||
@@ -1999,7 +1999,7 @@ mark_deref(DB_Trie):-
|
||||
traverse_ptree(DB_Trie, DB_Term),
|
||||
(DB_Term = depth(List, Inter); DB_Term = breadth(List, Inter)),
|
||||
member(L, List),
|
||||
((islabel(L), not(deref(L, _))) ->
|
||||
((islabel(L), \+ deref(L, _)) ->
|
||||
asserta(deref(L, Inter))
|
||||
;
|
||||
true
|
||||
|
@@ -214,11 +214,11 @@
|
||||
|
||||
|
||||
% load library modules
|
||||
:- ensure_loaded(library(lists)).
|
||||
:- ensure_loaded(library(system)).
|
||||
:- use_module(library(lists)).
|
||||
:- use_module(library(system)).
|
||||
|
||||
% load our own modules
|
||||
:- ensure_loaded(os).
|
||||
:- use_module(os).
|
||||
|
||||
%========================================================================
|
||||
%=
|
||||
|
@@ -206,8 +206,8 @@
|
||||
|
||||
:- module(variable_elimination, [trie_check_for_and_cluster/1, trie_replace_and_cluster/2, clean_up/0, variable_elimination_stats/3]).
|
||||
|
||||
:- ensure_loaded(library(lists)).
|
||||
:- ensure_loaded(library(tries)).
|
||||
:- use_module(library(lists)).
|
||||
:- use_module(library(tries)).
|
||||
|
||||
:- use_module('flags', _, [problog_define_flag/5]).
|
||||
|
||||
@@ -373,7 +373,7 @@ last_cluster_element(L, Cluster, R):-
|
||||
|
||||
nocluster([], _).
|
||||
nocluster([H|T], L):-
|
||||
not(memberchk(H, L)),
|
||||
\+ memberchk(H, L),
|
||||
nocluster(T, L).
|
||||
|
||||
eliminate_list([], L, L).
|
||||
@@ -418,8 +418,8 @@ make_prob_fact(L, P, ID):-
|
||||
(clause(problog:problog_predicate(var_elimination, 1), true) ->
|
||||
true
|
||||
;
|
||||
assert(problog:problog_predicate(var_elimination, 1))
|
||||
assertz(problog:problog_predicate(var_elimination, 1))
|
||||
),
|
||||
assert(problog:problog_var_elimination(ID, L, P))
|
||||
assertz(problog:problog_var_elimination(ID, L, P))
|
||||
).
|
||||
|
||||
|
@@ -376,7 +376,8 @@ problog_var_timer_timeout(Variable):-
|
||||
%%% This is possible for future use %%%
|
||||
|
||||
:- use_module(library(timeout)).
|
||||
:- meta_predicate problog_var_time_out(:,_,_,_), problog_time_out(:,_,_,_).
|
||||
:- meta_predicate(problog_var_time_out(0, *, *, *)).
|
||||
:- meta_predicate(problog_time_out(0, *, *, *)).
|
||||
%
|
||||
% Problems with nesting, use with care
|
||||
% always succeeds returns Success = true/fail, Time = Msec taken/timeout
|
||||
|
Reference in New Issue
Block a user