----------------------------------------------------------------------- -- An example of Actor Prolog program. -- -- (c) 2012 IRE RAS Alexei A. Morozov -- ----------------------------------------------------------------------- import .. from "morozov/Java3D"; import .. from "morozov/Sound"; class 'Main' (specialized 'Canvas3D'): -- constant: -- bounds : BoundingSphere = 'BoundingSphere'({}); -- clicked_color : Appearance = 'Appearance'({ material: 'Material'({ emissiveColor: 'Emerald', lightingEnable: 'yes' }) }); entered_color : Appearance = 'Appearance'({ material: 'Material'({ emissiveColor: 'Lime', lightingEnable: 'yes' }) }); exited_color : Appearance = 'Appearance'({ material: 'Material'({ emissiveColor: 'Black', lightingEnable: 'yes' }) }); -- fontName : FontName = 'helvetica'; tessellationTolerance : TessellationTolerance = 1.0e-2; -- bold_font : Font3D = 'Font3D'({ fontName, fontSize: 230, fontStyle: ['bold'], extrudePath: 'FontExtrusion'({ depth: 0 }), tessellationTolerance }); normal_font : Font3D = 'Font3D'({ fontName, fontSize: 230, fontStyle: [], extrudePath: 'FontExtrusion'({ depth: 0 }), tessellationTolerance }); -- background_color = 'Black'; enable_scene_antialiasing = 'yes'; -- internal: -- clip_0 = ('Clip', name="jar:data/phone_button_0.wav"); clip_1 = ('Clip', name="jar:data/phone_button_1.wav"); clip_2 = ('Clip', name="jar:data/phone_button_2.wav"); clip_3 = ('Clip', name="jar:data/phone_button_3.wav"); clip_4 = ('Clip', name="jar:data/phone_button_4.wav"); clip_5 = ('Clip', name="jar:data/phone_button_5.wav"); clip_6 = ('Clip', name="jar:data/phone_button_6.wav"); clip_7 = ('Clip', name="jar:data/phone_button_7.wav"); clip_8 = ('Clip', name="jar:data/phone_button_8.wav"); clip_9 = ('Clip', name="jar:data/phone_button_9.wav"); -- calculator = ('SimpleCalculator', display=self); -- con = ('Console', x= 40, width= 40); -- constant: -- character_code_Sign = 16#B1#; character_code_Backspace = 16#2190#; character_code_Multiply = 16#D7#; character_code_Minus = 16#2212#; -- [ PREDICATES: -- imperative: -- one_button( Numerical, Numerical, STRING) = Node - (i,i,i); one_button( Numerical, Numerical, STRING, Text3D_VerticalAlignment, Numerical) = Node - (i,i,i,i,i); -- display(Numerical,Numerical) = Node - (i,i); -- point_light( Numerical, Numerical, Angle, TimeInterval, Color) = Node - (i,i,i,i,i); -- update_appearance_and_font (NodeLabels,Appearance,Font3D) - (i,i,i); update_appearance_and_font_of_node (NodeLabel,Appearance,Font3D) - (i,i,i); -- update_font(NodeLabels,Font3D) - (i,i); update_font_of_node(NodeLabel,Font3D) - (i,i); -- get_sound(NodeLabel,'Clip') - (i,o); get_numbered_sound(Numerical,'Clip') - (i,o); -- play_clip('Clip') - (i); -- process_mouse_click(NodeLabel) - (i); show_value(_) - (i); -- determ: -- concat(NodeLabel,NodeLabel,NodeLabel) - (i,o,i)(i,i,o); -- CLAUSES: -- goal:-!, clip_0 ? open, clip_1 ? open, clip_2 ? open, clip_3 ? open, clip_4 ? open, clip_5 ? open, clip_6 ? open, clip_7 ? open, clip_8 ? open, clip_9 ? open, -- Sign== ?codes_to_string([character_code_Sign]), Backspace== ?codes_to_string([character_code_Backspace]), Multiply== ?codes_to_string([character_code_Multiply]), Minus== ?codes_to_string([character_code_Minus]), -- Brightness== 1.0, HalfBrightness== Brightness / 2, -- DeltaX== 450, X_U1== DeltaX, X_U2== X_U1 + DeltaX, X_D1== - (DeltaX), X_D2== X_D1 - DeltaX, -- DeltaY== 320, Y_U1== DeltaY, Y_U2== Y_U1 + 220, Y_D1== - (DeltaY), Y_D2== Y_D1 - DeltaY, -- show([ 'TransformGroup'({ allowChildrenWrite: 'yes', transform3D: 'Transform3D'({ scale: 0.00059 }), branches: [ ?display(0,Y_U2), ?one_button(X_D2,Y_D2,"0"), ?one_button(X_D1,Y_D2,Sign), ?one_button(0,Y_D2,",",'ALIGN_TOP',0), ?one_button(X_D2,Y_D1,"1"), ?one_button(X_D1,Y_D1,"2"), ?one_button(0,Y_D1,"3"), ?one_button(X_D2,0,"4"), ?one_button(X_D1,0,"5"), ?one_button(0,0,"6"), ?one_button(X_D2,Y_U1,"7"), ?one_button(X_D1,Y_U1,"8"), ?one_button(0,Y_U1,"9"), ?one_button(X_U1,Y_U1,"/"), ?one_button(X_U1,0,Multiply,'ALIGN_CENTER',-35), ?one_button(X_U1,Y_D1,Minus,'ALIGN_CENTER',-60), ?one_button(X_U1,Y_D2,"+",'ALIGN_CENTER',-27), ?one_button(X_U2,Y_U1,"C"), ?one_button(X_U2,0,Backspace,'ALIGN_TOP',11), ?one_button(X_U2,Y_D1,"%"), ?one_button(X_U2,Y_D2,"=",'ALIGN_TOP',-14) ] }), 'Background'({ color: background_color, applicationBounds: bounds }), 'AmbientLight'({ lightOn: 'yes', color: 'White', influencingBounds: bounds }), ?point_light(-0.5,0.5,(?'-'(?pi()) / 4),7300,color3(Brightness,0.0,0.0)), ?point_light(0.1,0.5,?'-'(?pi()),15100,color3(0.0,Brightness,0.0)), ?point_light(-0.5,0.1,(?pi() / 4),9100,color3(0.0,0.0,Brightness)), ?point_light(0.5,0.1,(?pi() / 8),5310,color3(HalfBrightness,HalfBrightness,0.0)), ?point_light(-0.1,-0.5,(?'-'(?pi()) / 8),11010,color3(0.0,HalfBrightness,HalfBrightness)), ?point_light(-0.5,-0.1,(?'-'(?pi()) / 3),8310,color3(HalfBrightness,0.0,HalfBrightness)), 'PickCanvas'({ handleMouseClicked: 'yes', handleMouseEntered: 'yes', handleMouseExited: 'yes', handleMousePressed: 'yes', handleMouseReleased: 'no', handleMouseDragged: 'no', handleMouseMoved: 'no', isPassive: 'no', period: 150, tolerance: 3, mode: 'GEOMETRY' }) ]), calculator ? display_current_value. -- one_button(X,Y,Text) = ?one_button(X,Y,Text,'ALIGN_CENTER',0). -- one_button(X,Y,Text,VerticalAlignment,Y0) = 'TransformGroup'({ allowChildrenWrite: 'yes', transform3D: 'Transform3D'({ translation: [X,Y,0] }), branches: [ 'Sphere'({ label: ?cast("NodeLabel",Text), radius: 150, divisions: 300, enableGeometryPicking: 'yes', enableAppearanceModify: 'yes', generateNormals: 'yes', generateNormalsInward: 'yes', appearance: 'Appearance'({ material: 'Material'({ ambientColor: 'Black', diffuseColor: 'Black', specularColor: 'White', emissiveColor: 'Black', shininess: 25 }) }) }), 'Shape3D'({ label: LetterLabel, allowGeometryRead: 'yes', allowAppearanceWrite: 'yes', geometry: 'Text3D'({ allowFont3DRead: 'yes', allowFont3DWrite: 'yes', font3D: normal_font, string: Text, position: p(0,Y0,0), horizontalAlignment: 'ALIGN_CENTER', verticalAlignment: VerticalAlignment, path: 'PATH_RIGHT', characterSpacing: 0.0 }), appearance: exited_color }) ] }) :- LetterLabel== "letter_" + Text. -- display(X,Y) = 'TransformGroup'({ allowChildrenWrite: 'yes', transform3D: 'Transform3D'({ translation: [X,Y,0] }), branches: [ 'Shape3D'({ label: "DISPLAY", allowGeometryRead: 'yes', allowAppearanceWrite: 'yes', geometry: 'Text3D'({ allowFont3DRead: 'yes', allowFont3DWrite: 'yes', allowStringRead: 'yes', allowStringWrite: 'yes', font3D: 'Font3D'({ fontName, fontSize: 270, fontStyle: [], extrudePath: 'FontExtrusion'({ depth: 0 }), tessellationTolerance }), string: "", position: p(0,0,0), horizontalAlignment: 'ALIGN_CENTER', verticalAlignment: 'ALIGN_CENTER', path: 'PATH_RIGHT', characterSpacing: 0.0 }), appearance: exited_color }) ] }). -- point_light(X0,Y0,RotZ,Increasing,C) = 'TransformGroup'({ allowTransformRead: 'yes', allowTransformWrite: 'yes', branches: [ 'TransformGroup'({ transform3D: 'Transform3D'({ translation: [X0,Y0,0.5] }), branches: [ 'PointLight'({ color: C, influencingBounds: Bounds }) ] }), 'RotationInterpolator'({ alpha: 'Alpha3D'({ increasingAlphaDuration: Increasing }), transformAxis: 'Transform3D'({ rotZ: RotZ }), schedulingBounds: Bounds }) ] }) :- Bounds== 'BoundingSphere'({radius: 10}). -- mouse_clicked([NodeLabel|_]):-!, update_font_of_node(NodeLabel,normal_font). -- mouse_entered([NodeLabel|_]):-!, update_appearance_and_font_of_node( NodeLabel,entered_color,normal_font). -- mouse_exited([NodeLabel|_]):-!, update_appearance_and_font_of_node( NodeLabel,exited_color,normal_font). -- mouse_pressed([NodeLabel|_]):-!, get_sound(NodeLabel,Clip), play_clip(Clip), update_appearance_and_font_of_node( NodeLabel,clicked_color,bold_font), process_mouse_click(NodeLabel). -- mouse_released(_):-!. -- mouse_dragged(_):-!. -- mouse_moved(_):-!. -- update_appearance_and_font([NL|Rest],Appearance,Font):-!, update_appearance_and_font_of_node(NL,Appearance,Font), update_appearance_and_font(Rest,Appearance,Font). update_appearance_and_font([],_,_). -- update_appearance_and_font_of_node("DISPLAY",_,_):-!. update_appearance_and_font_of_node(NodeLabel,Appearance,Font):- concat("letter_",_,NodeLabel),!, set_appearance(NodeLabel,Appearance), set_font3d(NodeLabel,Font). update_appearance_and_font_of_node(NodeLabel1,Appearance,Font):- concat("letter_",NodeLabel1,NodeLabel2),!, set_appearance(NodeLabel2,Appearance), set_font3d(NodeLabel2,Font). update_appearance_and_font_of_node(_,_,_). -- update_font([NL|Rest],Font):-!, update_font_of_node(NL,Font), update_font(Rest,Font). update_font([],_). -- update_font_of_node("DISPLAY",_):-!. update_font_of_node(NodeLabel,Font):- concat("letter_",_,NodeLabel),!, set_font3d(NodeLabel,Font). update_font_of_node(NodeLabel1,Font):- concat("letter_",NodeLabel1,NodeLabel2),!, set_font3d(NodeLabel2,Font). update_font_of_node(_,_). -- set_font3d(_,_):-!. -- get_sound(NodeLabel,Clip):- N== ?convert_to_integer(NodeLabel),!, get_numbered_sound(N,Clip). get_sound("/",Clip):-!, get_numbered_sound(1,Clip). get_sound("C",Clip):-!, get_numbered_sound(2,Clip). get_sound(Label,Clip):- Label == ?codes_to_string([character_code_Multiply]),!, get_numbered_sound(3,Clip). get_sound(Label,Clip):- Label == ?codes_to_string([character_code_Backspace]),!, get_numbered_sound(4,Clip). get_sound(Label,Clip):- Label == ?codes_to_string([character_code_Minus]),!, get_numbered_sound(5,Clip). get_sound("%",Clip):-!, get_numbered_sound(6,Clip). get_sound(",",Clip):-!, get_numbered_sound(7,Clip). get_sound(Label,Clip):- Label == ?codes_to_string([character_code_Sign]),!, get_numbered_sound(8,Clip). get_sound("+",Clip):-!, get_numbered_sound(9,Clip). get_sound("=",Clip):-!, get_numbered_sound(0,Clip). get_sound(_,Clip):- get_numbered_sound(0,Clip). -- get_numbered_sound(0,clip_0):-!. get_numbered_sound(1,clip_1):-!. get_numbered_sound(2,clip_2):-!. get_numbered_sound(3,clip_3):-!. get_numbered_sound(4,clip_4):-!. get_numbered_sound(5,clip_5):-!. get_numbered_sound(6,clip_6):-!. get_numbered_sound(7,clip_7):-!. get_numbered_sound(8,clip_8):-!. get_numbered_sound(9,clip_9):-!. get_numbered_sound(_,clip_0). -- play_clip(Clip):- Clip ? stop, Clip ? set_frame_position(0), Clip ? start,!. play_clip(_). -- process_mouse_click(Label):- N== ?convert_to_integer(Label),!, calculator ? enter_digit(N). process_mouse_click(Label):- Label == ?codes_to_string([character_code_Sign]),!, calculator ? change_sign. process_mouse_click(","):-!, calculator ? begin_fractional_part. process_mouse_click("C"):-!, calculator ? reset. process_mouse_click(Label):- Label == ?codes_to_string([character_code_Backspace]),!, calculator ? backspace. process_mouse_click("+"):-!, calculator ? operation('plus'). process_mouse_click(Label):- Label == ?codes_to_string([character_code_Minus]),!, calculator ? operation('minus'). process_mouse_click(Label):- Label == ?codes_to_string([character_code_Multiply]),!, calculator ? operation('multiply'). process_mouse_click("/"):-!, calculator ? operation('divide'). process_mouse_click("="):-!, calculator ? enter. process_mouse_click("%"):-!, calculator ? percent. process_mouse_click(_). -- show_value(V):- set_string("DISPLAY",V). ] class 'SimpleCalculator' (specialized 'Database'): -- internal: -- display : 'Main'; -- text_operations = ('Text'); -- con = ('Console'); -- [ DOMAINS: -- Target = sign(INTEGER); integer_part(INTEGER); 'has_fractional_part'; fractional_part(INTEGER,INTEGER); first_argument( INTEGER,INTEGER,INTEGER,INTEGER); second_argument( INTEGER,INTEGER,INTEGER,INTEGER); current_operation(Operation); 'first_argument_is_displayed'; 'result_is_displayed'. Operation = 'plus'; 'minus'; 'multiply'; 'divide'. -- PREDICATES: -- imperative: -- reset; prepare_display_if_necessary; clear_display; -- enter_digit(INTEGER) - (i); percent; change_sign; begin_fractional_part; backspace; -- operation(Operation) - (i); enter; -- remember_second_argument; -- implement_operation( INTEGER /* Sign */, INTEGER /* IntegerPart */, INTEGER /* FractionalPart */, INTEGER /* Counter */, Operation) - (i,i,i,i,i); implement_operation( INTEGER /* Sign */, INTEGER /* IntegerPart */, INTEGER /* FractionalPart */, INTEGER /* Counter */, INTEGER /* Sign */, INTEGER /* IntegerPart */, INTEGER /* FractionalPart */, INTEGER /* Counter */, Operation) - (i,i,i,i,i,i,i,i,i); implement_operation( Numerical, Numerical, Operation) = Numerical - (i,i,i); -- determ: -- is_zero(Numerical) - (i); -- imperative: -- assemble_number( INTEGER /* Sign */, INTEGER /* IntegerPart */, INTEGER /* FractionalPart */, INTEGER /* Counter */) = Numerical - (i,i,i,i); -- dismantle_number( Numerical, INTEGER /* Sign */, INTEGER /* IntegerPart */, INTEGER /* FractionalPart */, INTEGER /* Counter */) - (i,o,o,o,o); dismantle_number( Numerical, INTEGER /* IntegerPart */, INTEGER /* FractionalPart */, INTEGER /* Counter */) - (i,o,o,o); -- determ: -- search_dot(STRING) = INTEGER - (i); -- imperative: -- count_nonzero_digits (STRING,STRING,INTEGER,INTEGER) - (i,o,i,o); -- determ: -- are_zeros(STRING) - (i); -- imperative: -- convert_number(INTEGER,STRING) = INTEGER - (i,i); -- update_current_value( INTEGER /* Sign */, INTEGER /* IntegerPart */, INTEGER /* FractionalPart */, INTEGER /* Counter */) - (i,i,i,i); -- display_current_value; display_current_value(INTEGER) - (i); -- get_current_value( INTEGER /* Sign */, INTEGER /* IntegerPart */, INTEGER /* FractionalPart */, INTEGER /* Counter */) - (o,o,o,o); -- get_sign(INTEGER) - (o); sign_to_text(INTEGER,STRING) - (i,o); -- determ: -- get_fractional_part_or_Fail(INTEGER,INTEGER) - (o,o); -- imperative: -- get_integer_part(INTEGER) - (o); -- '+'(Numerical,Numerical) = Numerical - (i,i); '-'(Numerical,Numerical) = Numerical - (i,i); '-'(Numerical) = Numerical - (i); '*'(Numerical,Numerical) = Numerical - (i,i); '/'(Numerical,Numerical) = Numerical - (i,i); -- CLAUSES: -- reset:- retract_all, display_current_value. -- prepare_display_if_necessary:- find('result_is_displayed'),!, retract_all('result_is_displayed'), clear_display. prepare_display_if_necessary:- find('first_argument_is_displayed'),!, retract_all('first_argument_is_displayed'), clear_display. prepare_display_if_necessary. -- clear_display:- retract_all('has_fractional_part'), retract_all(sign(_)), retract_all(integer_part(_)), retract_all(fractional_part(_,_)). -- enter_digit(_):- prepare_display_if_necessary, fail. enter_digit(Digit):- Item== ?match(fractional_part(_,_)), Item == fractional_part(N1,C1),!, N2== N1 * 10 + Digit, C2== C1 + 1, retract_all(fractional_part(_,_)), insert(fractional_part(N2,C2)), display_current_value. enter_digit(N2):- find('has_fractional_part'),!, insert(fractional_part(N2,1)), display_current_value. enter_digit(Digit):- Item== ?match(integer_part(_)), Item == integer_part(N1),!, N2== N1 * 10 + Digit, retract_all(integer_part(_)), insert(integer_part(N2)), display_current_value. enter_digit(N2):- insert(integer_part(N2)), display_current_value. -- percent:- Item1== ?match(first_argument(_,_,_,_)), Item1 == first_argument( Sign1,IntegerPart1,FractionalPart1,Counter1),!, get_current_value( Sign2,IntegerPart2,FractionalPart2,Counter2), V1== ?assemble_number( Sign1,IntegerPart1,FractionalPart1,Counter1), V2== ?assemble_number( Sign2,IntegerPart2,FractionalPart2,Counter2), V3== V1 / 100 * V2, dismantle_number( V3,Sign3,IntegerPart3,FractionalPart3,Counter3), update_current_value( Sign3,IntegerPart3,FractionalPart3,Counter3), display_current_value. percent. -- change_sign:- prepare_display_if_necessary, fail. change_sign:- Item== ?match(sign(_)), Item == sign(N1),!, N2== - (N1), retract_all(sign(_)), insert(sign(N2)), display_current_value(N2). change_sign:- N2== -1, insert(sign(N2)), display_current_value(N2). -- begin_fractional_part:- prepare_display_if_necessary, fail. begin_fractional_part:- find('has_fractional_part'),!. begin_fractional_part:- insert('has_fractional_part'), display_current_value. -- backspace:- prepare_display_if_necessary, fail. backspace:- Item== ?match(fractional_part(_,_)), Item == fractional_part(_,1),!, retract_all(fractional_part(_,_)), display_current_value. backspace:- Item== ?match(fractional_part(_,_)), Item == fractional_part(N1,C1),!, N2== ?div(N1,10), C2== C1 - 1, retract_all(fractional_part(_,_)), insert(fractional_part(N2,C2)), display_current_value. backspace:- find('has_fractional_part'),!, retract_all('has_fractional_part'), display_current_value. backspace:- Item== ?match(integer_part(_)), Item == integer_part(N1),!, N2== ?div(N1,10), retract_all(integer_part(_)), insert(integer_part(N2)), display_current_value. backspace. -- operation(Operation):- find('result_is_displayed'),!, retract_all(current_operation(_)), insert(current_operation(Operation)). operation(Operation):- find('first_argument_is_displayed'),!, retract_all(current_operation(_)), insert(current_operation(Operation)). operation(Operation):- get_current_value( Sign,IntegerPart,FractionalPart,Counter), retract_all(first_argument(_,_,_,_)), retract_all(second_argument(_,_,_,_)), retract_all(current_operation(_)), retract_all('first_argument_is_displayed'), insert(first_argument( Sign,IntegerPart, FractionalPart,Counter)), insert(current_operation(Operation)), insert('first_argument_is_displayed'). -- enter:- find('result_is_displayed'), Item1== ?match(first_argument(_,_,_,_)), Item2== ?match(current_operation(_)), Item1 == first_argument( Sign,IntegerPart,FractionalPart,Counter), Item2 == current_operation(Operation),!, implement_operation( Sign,IntegerPart,FractionalPart,Counter, Operation). enter:- remember_second_argument, Item1== ?match(first_argument(_,_,_,_)), Item2== ?match(current_operation(_)), Item1 == first_argument( Sign,IntegerPart,FractionalPart,Counter), Item2 == current_operation(Operation),!, implement_operation( Sign,IntegerPart,FractionalPart,Counter, Operation). enter. -- remember_second_argument:- get_current_value( Sign,IntegerPart,FractionalPart,Counter), retract_all(second_argument(_,_,_,_)), insert(second_argument( Sign,IntegerPart, FractionalPart,Counter)). -- implement_operation( Sign1,IntegerPart1,FractionalPart1,Counter1, Operation):- Item1== ?match(second_argument(_,_,_,_)), Item1 == second_argument( Sign2,IntegerPart2,FractionalPart2,Counter2),!, implement_operation( Sign1,IntegerPart1,FractionalPart1,Counter1, Sign2,IntegerPart2,FractionalPart2,Counter2, Operation). implement_operation(_,_,_,_,_):- break('implement_operation'). -- implement_operation( Sign1,IntegerPart1,FractionalPart1,Counter1, Sign2,IntegerPart2,FractionalPart2,Counter2, Operation):- V1== ?assemble_number( Sign1,IntegerPart1,FractionalPart1,Counter1), V2== ?assemble_number( Sign2,IntegerPart2,FractionalPart2,Counter2), V3== ?implement_operation(V1,V2,Operation), dismantle_number( V3,Sign3,IntegerPart3,FractionalPart3,Counter3), retract_all(first_argument(_,_,_,_)), insert(first_argument( Sign3,IntegerPart3, FractionalPart3,Counter3)), update_current_value( Sign3,IntegerPart3,FractionalPart3,Counter3), insert('result_is_displayed'), display_current_value. -- implement_operation(V1,V2,'plus') = V1 + V2 :-!. implement_operation(V1,V2,'minus') = V1 - V2 :-!. implement_operation(V1,V2,'multiply') = V1 * V2 :-!. implement_operation(V1,V2,'divide') = V1 :- is_zero(V2),!, con ? error("Division by zero error!"). implement_operation(V1,V2,'divide') = V1 / V2. -- is_zero(0):-!. is_zero(0.0). -- assemble_number(Sign,IP,0,_) = Value :-!, Value== Sign * IP. assemble_number(Sign,IP,FP,Counter) = Value :- Format== text_operations?format("%%s%%d.%%0%dd",Counter), sign_to_text(Sign,ST), SignedValue== text_operations?format(Format,ST,IP,FP), Value== ?convert_to_real(SignedValue),!. assemble_number(_,_,_,_) = _ :- break('assemble_number'). -- dismantle_number(V1,-1,IP,FP,Counter):- V1 < 0,!, V2== -(V1), dismantle_number(V2,IP,FP,Counter). dismantle_number(V,1,IP,FP,Counter):- dismantle_number(V,IP,FP,Counter). -- dismantle_number(V1,V2,0,0):- V2== ?val("INTEGER",V1),!. dismantle_number(V,IP,FP,Counter):- -- Text== text_operations?format("%1.15f",V), Text== text_operations?format("%1.14f",V), P1== ?search_dot(Text), P2== P1 - 1, text_operations?split(P2,Text,Front,Rest1), text_operations?split(1,Rest1,_,Rest2), IP== ?convert_to_integer(Front),!, count_nonzero_digits(Rest2,Rest3,0,Counter), FP== ?convert_number(Counter,Rest3). dismantle_number(_,_,_,_):- break('dismantle_number'). -- search_dot(Text) = P :- P== text_operations?search(Text,"."),!. search_dot(Text) = P :- P== text_operations?search(Text,","),!. -- count_nonzero_digits(S1,"",Counter,Counter):- are_zeros(S1),!. count_nonzero_digits(S1,S4,C1,C2):- text_operations?split(1,S1,Digit,S2),!, count_nonzero_digits(S2,S3,C1+1,C2), text_operations?concat(Digit,S3,S4). count_nonzero_digits(_,"",Counter,Counter). -- are_zeros(S1):- text_operations?concat("0",S2,S1),!, are_zeros(S2). are_zeros(""). -- convert_number(0,_) = 0 :- !. convert_number(_,Text) = N :- N== ?convert_to_integer(Text),!. convert_number(_,_) = _ :- break('convert_number_if_necessary'). -- update_current_value(_,_,_,_):- clear_display, fail. update_current_value(Sign,IP,0,_):-!, insert(sign(Sign)), insert(integer_part(IP)). update_current_value(Sign,IP,FP,Counter):- insert('has_fractional_part'), insert(sign(Sign)), insert(integer_part(IP)), insert(fractional_part(FP,Counter)). -- display_current_value:- get_sign(Sign), display_current_value(Sign). -- display_current_value(Sign):- get_fractional_part_or_Fail(FractionalPart,Counter),!, sign_to_text(Sign,ST), get_integer_part(IntegerPart), Format== text_operations?format("%%s%%d,%%0%dd",Counter), SignedValue== text_operations?format( Format,ST,IntegerPart,FractionalPart), display ? show_value(SignedValue). display_current_value(Sign):- find('has_fractional_part'),!, sign_to_text(Sign,ST), get_integer_part(IntegerPart), display ? show_value( text_operations?format("%s%d,",ST,IntegerPart)). display_current_value(Sign):- sign_to_text(Sign,ST), get_integer_part(IntegerPart), display ? show_value( text_operations?format("%s%d",ST,IntegerPart)). -- get_current_value(Sign,IntegerPart,FractionalPart,Counter):- get_fractional_part_or_Fail(FractionalPart,Counter),!, get_sign(Sign), get_integer_part(IntegerPart). get_current_value(Sign,IntegerPart,0,0):- get_sign(Sign), get_integer_part(IntegerPart). -- get_sign(Sign):- Item== ?match(sign(_)), Item == sign(Sign),!. get_sign(1). -- sign_to_text(-1,"-"):-!. sign_to_text(_,""). -- get_fractional_part_or_Fail(N,Counter):- Item== ?match(fractional_part(_,_)), Item == fractional_part(N,Counter),!. -- get_integer_part(N):- Item== ?match(integer_part(_)), Item == integer_part(N),!. get_integer_part(0). ] |