build_colored_graph(truth, pred, _) :-
!.
build_colored_graph(falsity, pred, _) :-
!.
build_colored_graph(Expr, _, RootNodeId) :-
( Expr = set_extension(List)
; Expr = sequence_extension(List)
; Expr = rec(List)
),
!,
build_colored_graph_from_set(List, RootNodeId).
build_colored_graph(Expr, Type, RootNodeId) :-
( Expr = let_predicate(Ids, EqVals, Body)
; Expr = let_expression(Ids, EqVals, Body)
; Expr = lazy_let_pred(Ids, EqVals, Body)
),
!,
% non-commutative
zip_to_equalities_conj(Ids, EqVals, EqsConj),
get_texpr_expr_functor_and_type(EqsConj, EqsExpr, EqsType, EqsFunctor),
get_texpr_expr_functor_and_type(Body, BodyExpr, BodyType, BodyFunctor),
add_term_and_symbol_nodes_to_graph(EqsExpr, EqsType, EqsFunctor, EqsRootNodeId),
add_term_and_symbol_nodes_to_graph(BodyExpr, BodyType, BodyFunctor, BodyRootNodeId),
add_node_to_colored_graph(arg, EqsExpr, EqsType, EqsNodeId),
add_node_to_colored_graph(arg, BodyExpr, BodyType, BodyNodeId),
bliss_interface:add_edge(EqsNodeId, EqsRootNodeId),
bliss_interface:add_edge(BodyNodeId, BodyRootNodeId),
bliss_interface:add_edge(EqsNodeId, BodyNodeId),
bliss_interface:add_edge(RootNodeId, EqsNodeId),
build_colored_graph(EqsExpr, EqsType, EqsRootNodeId),
build_colored_graph(BodyExpr, Type, BodyRootNodeId).
build_colored_graph(partition(Set,AstList), _, RootNodeId) :-
!,
get_texpr_expr_functor_and_type(Set, SetExpr, SetType, SetFunctor),
add_term_and_symbol_nodes_to_graph(SetExpr, SetType, SetFunctor, SetRootNodeId),
add_nodes_from_ast_list_commutative(RootNodeId, AstList),
add_node_to_colored_graph(arg, SetExpr, SetType, SetNodeId),
bliss_interface:add_edge(SetNodeId, SetRootNodeId),
bliss_interface:add_edge(RootNodeId, SetNodeId),
build_colored_graph(SetExpr, SetType, SetRootNodeId).
build_colored_graph(if_then_else(Cond,If,Else), _, RootNodeId) :-
% non-commutative
!,
get_texpr_expr_functor_and_type(Cond, CondExpr, CondType, CondFunctor),
get_texpr_expr_functor_and_type(If, IfExpr, IfType, IfFunctor),
get_texpr_expr_functor_and_type(Else, ElseExpr, ElseType, ElseFunctor),
add_term_and_symbol_nodes_to_graph(CondExpr, CondType, CondFunctor, CondRootNodeId),
add_term_and_symbol_nodes_to_graph(IfExpr, IfType, IfFunctor, IfRootNodeId),
add_term_and_symbol_nodes_to_graph(ElseExpr, ElseType, ElseFunctor, ElseRootNodeId),
add_node_to_colored_graph(arg, CondExpr, CondType, CondNodeId),
add_node_to_colored_graph(arg, IfExpr, IfType, IfNodeId),
add_node_to_colored_graph(arg, ElseExpr, ElseType, ElseNodeId),
bliss_interface:add_edge(CondNodeId, CondRootNodeId),
bliss_interface:add_edge(IfNodeId, IfRootNodeId),
bliss_interface:add_edge(ElseNodeId, ElseRootNodeId),
bliss_interface:add_edge(CondNodeId, IfNodeId),
bliss_interface:add_edge(IfNodeId, ElseNodeId),
bliss_interface:add_edge(RootNodeId, CondNodeId),
build_colored_graph(CondExpr, CondType, CondRootNodeId),
build_colored_graph(IfExpr, IfType, IfRootNodeId),
build_colored_graph(ElseExpr, ElseType, ElseRootNodeId).
build_colored_graph(assertion_expression(Cond,_ErrMsg,Expr), _, RootNodeId) :-
% non-commutative
!,
get_texpr_expr_functor_and_type(Cond, CondExpr, CondType, CondFunctor),
get_texpr_expr_functor_and_type(Expr, ExprExpr, ExprType, ExprFunctor),
add_term_and_symbol_nodes_to_graph(CondExpr, CondType, CondFunctor, CondRootNodeId),
add_term_and_symbol_nodes_to_graph(ExprExpr, ExprType, ExprFunctor, ExprRootNodeId),
add_node_to_colored_graph(arg, CondExpr, CondType, CondNodeId),
add_node_to_colored_graph(arg, ExprExpr, ExprType, ExprNodeId),
bliss_interface:add_edge(CondNodeId, CondRootNodeId),
bliss_interface:add_edge(ExprNodeId, ExprRootNodeId),
bliss_interface:add_edge(CondNodeId, ExprNodeId),
bliss_interface:add_edge(RootNodeId, CondNodeId),
build_colored_graph(CondExpr, CondType, CondRootNodeId),
build_colored_graph(ExprExpr, ExprType, ExprRootNodeId).
build_colored_graph(forall(Ids,Lhs,Rhs), pred, RootNodeId) :-
!,
( Lhs = b(truth,pred,_) % typing information might have been removed
-> Body = Rhs
; Body = b(implication(Lhs,Rhs),pred,[])
),
create_nodes_for_ids(Ids),
get_texpr_expr_functor_and_type(Body, BodyExpr, BodyType, BodyFunctor),
add_term_and_symbol_nodes_to_graph(BodyExpr, BodyType, BodyFunctor, ArgRootNodeId),
add_node_to_colored_graph(arg, BodyExpr, BodyType, ArgNodeId),
bliss_interface:add_edge(ArgNodeId, ArgRootNodeId),
bliss_interface:add_edge(RootNodeId, ArgNodeId),
build_colored_graph(BodyExpr, BodyType, ArgRootNodeId).
build_colored_graph(Expr, _, RootNodeId) :-
( Expr = comprehension_set(Ids,Body)
; Expr = exists(Ids,Body)
),
!,
create_nodes_for_ids(Ids),
get_texpr_expr_functor_and_type(Body, BodyExpr, BodyType, BodyFunctor),
add_term_and_symbol_nodes_to_graph(BodyExpr, BodyType, BodyFunctor, ArgRootNodeId),
add_node_to_colored_graph(arg, BodyExpr, BodyType, ArgNodeId),
bliss_interface:add_edge(ArgNodeId, ArgRootNodeId),
bliss_interface:add_edge(RootNodeId, ArgNodeId),
build_colored_graph(BodyExpr, BodyType, ArgRootNodeId).
build_colored_graph(Fun, _, RootNodeId) :-
functor(Fun, Functor, 3),
member(Functor, [lambda,general_sum,general_product,quantified_union,quantified_intersection]),
arg(2, Fun, Pred),
arg(3, Fun, LExpr),
% non-commutative
!,
get_texpr_expr_functor_and_type(LExpr, LExprExpr, LExprType, LExprFunctor),
get_texpr_expr_functor_and_type(Pred, PredExpr, PredType, PredFunctor),
add_term_and_symbol_nodes_to_graph(LExpr, LExprExpr, LExprFunctor, LExprRootNodeId),
add_term_and_symbol_nodes_to_graph(Pred, PredType, PredFunctor, PredRootNodeId),
add_node_to_colored_graph(arg, LExprExpr, LExprType, LExprNodeId),
add_node_to_colored_graph(arg, PredExpr, PredType, PredNodeId),
bliss_interface:add_edge(LExprNodeId, LExprRootNodeId),
bliss_interface:add_edge(PredNodeId, PredRootNodeId),
bliss_interface:add_edge(LExprNodeId, PredNodeId),
bliss_interface:add_edge(RootNodeId, LExprNodeId),
build_colored_graph(LExprExpr, LExprType, LExprRootNodeId),
build_colored_graph(PredExpr, PredType, PredRootNodeId).
build_colored_graph(record_field(Record, FieldName), Type, RootNodeId) :-
% treated as a non-commutative operator but needs special case since the field name is just a Prolog atom and no B AST node
!,
get_texpr_expr_functor_and_type(Record, RecordExpr, RecordType, RecordFunctor),
add_term_and_symbol_nodes_to_graph(RecordExpr, RecordType, RecordFunctor, RecordRootNodeId),
( have_seen_expr(FieldName, Type, TNodeId)
-> FieldNameRootNodeId = TNodeId
; get_next_color(Color),
bliss_interface:add_node(FieldName, Color, FieldNameRootNodeId),
log_seen_expr(FieldName, Type, FieldNameRootNodeId)
%asserta(ast_to_node_id(Term,Type,RootNodeId))
%asserta(node_id_to_ast(RootNodeId,b(Term,Type,[])))
),
add_node_to_colored_graph(arg, RecordExpr, RecordType, RecordNodeId),
add_node_to_colored_graph(arg, FieldName, record_key, FieldNameNodeId), % use an artificial type record_key
% one edge from the argument node to the argument's root node
bliss_interface:add_edge(RecordNodeId, RecordRootNodeId),
bliss_interface:add_edge(FieldNameNodeId, FieldNameRootNodeId),
% edge from first to second argument to represent the ordering
bliss_interface:add_edge(RecordNodeId, FieldNameNodeId),
% add an edge from the root node to the first argument's argument node
bliss_interface:add_edge(RootNodeId, RecordNodeId),
build_colored_graph(RecordExpr, RecordType, RecordRootNodeId).
build_colored_graph(Binary, _Type, RootNodeId) :-
functor(Binary, Functor, Arity),
Arity == 2,
is_associative(Functor),
!,
split_associative_node(Binary, AstList),
add_nodes_from_ast_list_commutative(RootNodeId, AstList).
build_colored_graph(Binary, _Type, RootNodeId) :-
functor(Binary, Functor, Arity),
Arity == 2,
\+ is_binary_interpreted_symbol(Binary),
!,
arg(1, Binary, Arg1),
arg(2, Binary, Arg2),
get_texpr_expr_functor_and_type(Arg1, Arg1Expr, Arg1Type, Arg1Functor),
get_texpr_expr_functor_and_type(Arg2, Arg2Expr, Arg2Type, Arg2Functor),
% root nodes for arguments
add_term_and_symbol_nodes_to_graph(Arg1Expr, Arg1Type, Arg1Functor, Arg1RootNodeId),
add_term_and_symbol_nodes_to_graph(Arg2Expr, Arg2Type, Arg2Functor, Arg2RootNodeId),
( is_commutative_but_not_associative(Functor)
-> % add an edge from the root node to the root node of each argument
bliss_interface:add_edge(RootNodeId, Arg1RootNodeId),
bliss_interface:add_edge(RootNodeId, Arg2RootNodeId)
; % special argument node for each argument
add_node_to_colored_graph(arg, Arg1Expr, Arg1Type, Arg1NodeId),
add_node_to_colored_graph(arg, Arg2Expr, Arg2Type, Arg2NodeId),
% one edge from the argument node to the argument's root node
bliss_interface:add_edge(Arg1NodeId, Arg1RootNodeId),
bliss_interface:add_edge(Arg2NodeId, Arg2RootNodeId),
% edge from first to second argument to represent the ordering
bliss_interface:add_edge(Arg1NodeId, Arg2NodeId),
% add an edge from the root node to the first argument's argument node
bliss_interface:add_edge(RootNodeId, Arg1NodeId)
),
build_colored_graph(Arg1Expr, Arg1Type, Arg1RootNodeId),
build_colored_graph(Arg2Expr, Arg2Type, Arg2RootNodeId).
build_colored_graph(Term, _, _) :-
( is_interpreted_symbol(Term)
; is_uninterpreted_symbol(Term)
),
!.
build_colored_graph(Unary, _Type, RootNodeId) :-
functor(Unary, _Functor, Arity),
Arity == 1,
!,
arg(1, Unary, Arg),
get_texpr_expr_functor_and_type(Arg, ArgExpr, ArgType, ArgFunctor),
% root node for argument
add_term_and_symbol_nodes_to_graph(ArgExpr, ArgType, ArgFunctor, ArgRootNodeId),
% special argument node for each argument
add_node_to_colored_graph(arg, ArgExpr, ArgType, ArgNodeId),
% one edge from the argument node to the argument's root node
bliss_interface:add_edge(ArgNodeId, ArgRootNodeId),
% add an edge from the root node to the first argument's argument node
bliss_interface:add_edge(RootNodeId, ArgNodeId),
build_colored_graph(ArgExpr, ArgType, ArgRootNodeId).
build_colored_graph(Expr, _Type, _ExprRootNodeId) :-
add_warning(smt_symmetry_breaking, 'Missing implementation in build_colored_graph/3 for: ', [Expr]), !,
fail.