├── .atom
└── ide-reason.json
├── .gitignore
├── .ocp-indent
├── Makefile
├── OCalc.opam
├── README.md
├── assets
├── 404.html
├── Roboto-Regular.ttf
├── camel.png
├── drapeau_eng.png
├── drapeau_fr.png
├── dune
├── gl-matrix-min.js
├── gl-matrix-min.js-old
├── include.math
├── index.html
├── index.js
├── logo.png
└── pi.png
├── create-release.sh
├── dune
├── dune-project
├── equation.ml
├── equation0.equ
├── equation1.equ
├── equation2.equ
├── equation3.equ
├── equation4.equ
├── equation5.equ
├── equation6.equ
├── matrix.ml
├── package.json
└── src
├── interfaces
├── commune.ml
├── dune
├── topCmd.ml
├── topCmd.mli
├── topFichiers.ml
├── topFichiers.mli
├── topGui.ml
├── topGui.mli
├── topServeur.ml
├── topServeur.mli
├── topTest.ml
└── topTest.mli
├── modules
├── I18n.ml
├── I18n.mli
├── dune
├── grandEntier_off.ml
├── grandEntier_off.mli
├── grandEntier_on.ml
├── grandEntier_on.mli
├── grandNum_on.ml
├── grandNum_on.mli
├── grandRationnel_on.ml
├── grandReel_on.ml
├── grandReel_on.mli
├── matrix.ml
└── matrix.mli
└── noyau
├── ancien_moteur.ml
├── ancien_moteur.mli
├── dune
├── lexer.ml
├── lexer.mli
├── lien.ml
├── moteur.ml
├── moteur.mli
├── nouveau_lexer.ml
├── nouveau_lexer.mli
├── nouveau_parser.ml
├── nouveau_parser.mli
├── nouveau_type.ml
├── parser.ml
├── parser.mli
├── type.ml
├── type.mli
├── utils.ml
└── utils.mli
/.atom/ide-reason.json:
--------------------------------------------------------------------------------
1 | {
2 | "server": {
3 | "tool": "rls"
4 | },
5 | "rls": {
6 | "refmt": "",
7 | "lispRefmt": "",
8 | "format_width": 80,
9 | "autoRebuild": true
10 | },
11 | "ols": {
12 | "codelens": {
13 | "enabled": true,
14 | "unicode": true
15 | },
16 | "debounce": {
17 | "linter": 500
18 | },
19 | "diagnostics": {
20 | "merlinPerfLogging": false,
21 | "tools": [
22 | "merlin"
23 | ]
24 | },
25 | "format": {
26 | "width": null
27 | },
28 | "path": {
29 | "bsb": "./node_modules/bs-platform/lib/bsb.exe",
30 | "env": "env",
31 | "esy": "esy",
32 | "ocamlfind": "ocamlfind",
33 | "ocamlmerlin": "ocamlmerlin",
34 | "ocpindent": "ocp-indent",
35 | "opam": "opam",
36 | "rebuild": "rebuild",
37 | "refmt": "refmt",
38 | "refmterr": "refmterr",
39 | "rtop": "rtop"
40 | },
41 | "server": {
42 | "languages": [
43 | "ocaml",
44 | "reason"
45 | ]
46 | }
47 | },
48 | "autocompleteResultsFirst": true
49 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | test
3 | *.cm*
4 | *~
5 | src2
6 | obj/lien.ml
7 | bin
8 | a.out
9 | esy.lock
10 | _esy
11 | node_modules
12 | .o
13 | .a
14 | .exe
15 | .merlin
16 | OCalc.install
17 |
--------------------------------------------------------------------------------
/.ocp-indent:
--------------------------------------------------------------------------------
1 | normal
2 | with=0
3 | syntax=lwt mll
4 | max_indent=2
5 | ppx_stritem_ext=0
6 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | SRC=type.ml utils.ml lexer.ml parser.ml grandEntier.mli grandEntier.ml
2 | SRC_TEST=$(SRC) test.ml
3 | SRC_BUILD=$(SRC) toplevel.ml
4 | SRC_INTERPRETE=$(SRC) interprete.ml
5 |
6 | build: $(SRC_BUILD)
7 | ocamlc $^ -o $@
8 | ./$@
9 | rm $@
10 |
11 | test: $(SRC_TEST)
12 | ocamlc $^ -o $@
13 | ./$@
14 | rm $@
15 |
16 | #-u -s option may speed up a little
17 |
18 | interprete:
19 | (sed -r 's/open (.*)/;;\n#use "\L\1.ml";;/g' $(SRC_INTERPRETE); echo \;\;; cat -) | ocaml
20 |
21 | eval:
22 | (sed -r 's/open (.*)/;;\n#use "\L\1.ml";;/g' $(SRC_INTERPRETE); echo \;\;) | ocaml
23 |
24 | clean:
25 | rm -f *.cm* *.html
26 | #*.css we will have our special stylesheet so don't remove it
27 |
28 | doc_build: build
29 | ocamldoc -html -all-params -colorize-code -charset utf-8 $(SRC_BUILD)
30 |
--------------------------------------------------------------------------------
/OCalc.opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | version: "dev"
3 | maintainer: [
4 | "elie.brami@epita.fr"
5 | "alexandre.mourgues@epita.fr"
6 | "gautier.habermann@epita.fr"
7 | "quentin.feugueur@epita.fr"
8 | ]
9 | author: [
10 | "elie.brami"
11 | "alexandre.mourgues"
12 | "gautier.habermann"
13 | "quentin.feugueur"
14 | ]
15 | build: [
16 |
17 | ]
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ocalc
2 |
3 | This project is a formal calculator made in OCaml
4 |
5 | ## How to install on Windows
6 |
7 | 1. Download as a zip and unzip or clone the repository
8 | 2. Execute `install_deps.bat` (It will install the cygwin dependencies, only choose the mirror and then next ... next)
9 | 3. Execute `compile.bat` (It will compile the project)
10 | 4. Launch by executing `launch.bat`
11 |
--------------------------------------------------------------------------------
/assets/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Page non trouvé
7 |
15 |
16 |
17 |
18 | Page non trouvé
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/assets/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/assets/camel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/camel.png
--------------------------------------------------------------------------------
/assets/drapeau_eng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/drapeau_eng.png
--------------------------------------------------------------------------------
/assets/drapeau_fr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/drapeau_fr.png
--------------------------------------------------------------------------------
/assets/dune:
--------------------------------------------------------------------------------
1 | (install
2 | (section bin)
3 | (package OCalc)
4 | (files
5 | Roboto-Regular.ttf
6 | logo.png
7 | pi.png
8 | camel.png
9 | drapeau_fr.png
10 | drapeau_eng.png
11 | index.html
12 | 404.html
13 | index.js
14 | include.math
15 | (../src/interfaces/topGui.bc.js as OCalc.bc.js)
16 | gl-matrix-min.js))
17 |
--------------------------------------------------------------------------------
/assets/gl-matrix-min.js-old:
--------------------------------------------------------------------------------
1 | /*!
2 | @fileoverview gl-matrix - High performance matrix and vector operations
3 | @author Brandon Jones
4 | @author Colin MacKenzie IV
5 | @version 3.0.0
6 |
7 | Copyright (c) 2015-2019, Brandon Jones, Colin MacKenzie IV.
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy
10 | of this software and associated documentation files (the "Software"), to deal
11 | in the Software without restriction, including without limitation the rights
12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 | copies of the Software, and to permit persons to whom the Software is
14 | furnished to do so, subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in
17 | all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 | THE SOFTWARE.
26 |
27 | */
28 | !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t=t||self).glMatrix={})}(this,function(t){"use strict";var n=1e-6,a="undefined"!=typeof Float32Array?Float32Array:Array,r=Math.random;var u=Math.PI/180;Math.hypot||(Math.hypot=function(){for(var t=0,n=arguments.length;n--;)t+=arguments[n]*arguments[n];return Math.sqrt(t)});var e=Object.freeze({EPSILON:n,get ARRAY_TYPE(){return a},RANDOM:r,setMatrixArrayType:function(t){a=t},toRadian:function(t){return t*u},equals:function(t,a){return Math.abs(t-a)<=n*Math.max(1,Math.abs(t),Math.abs(a))}});function o(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=a[0],c=a[1],h=a[2],s=a[3];return t[0]=r*i+e*c,t[1]=u*i+o*c,t[2]=r*h+e*s,t[3]=u*h+o*s,t}function i(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t[3]=n[3]-a[3],t}var c=o,h=i,s=Object.freeze({create:function(){var t=new a(4);return a!=Float32Array&&(t[1]=0,t[2]=0),t[0]=1,t[3]=1,t},clone:function(t){var n=new a(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},copy:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},identity:function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},fromValues:function(t,n,r,u){var e=new a(4);return e[0]=t,e[1]=n,e[2]=r,e[3]=u,e},set:function(t,n,a,r,u){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t},transpose:function(t,n){if(t===n){var a=n[1];t[1]=n[2],t[2]=a}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},invert:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=a*e-u*r;return o?(o=1/o,t[0]=e*o,t[1]=-r*o,t[2]=-u*o,t[3]=a*o,t):null},adjoint:function(t,n){var a=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=a,t},determinant:function(t){return t[0]*t[3]-t[2]*t[1]},multiply:o,rotate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=Math.sin(a),c=Math.cos(a);return t[0]=r*c+e*i,t[1]=u*c+o*i,t[2]=r*-i+e*c,t[3]=u*-i+o*c,t},scale:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=a[0],c=a[1];return t[0]=r*i,t[1]=u*i,t[2]=e*c,t[3]=o*c,t},fromRotation:function(t,n){var a=Math.sin(n),r=Math.cos(n);return t[0]=r,t[1]=a,t[2]=-a,t[3]=r,t},fromScaling:function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},str:function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},frob:function(t){return Math.hypot(t[0],t[1],t[2],t[3])},LDU:function(t,n,a,r){return t[2]=r[2]/r[0],a[0]=r[0],a[1]=r[1],a[3]=r[3]-t[2]*a[1],[t,n,a]},add:function(t,n,a){return t[0]=n[0]+a[0],t[1]=n[1]+a[1],t[2]=n[2]+a[2],t[3]=n[3]+a[3],t},subtract:i,exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=a[0],c=a[1],h=a[2],s=a[3];return Math.abs(r-i)<=n*Math.max(1,Math.abs(r),Math.abs(i))&&Math.abs(u-c)<=n*Math.max(1,Math.abs(u),Math.abs(c))&&Math.abs(e-h)<=n*Math.max(1,Math.abs(e),Math.abs(h))&&Math.abs(o-s)<=n*Math.max(1,Math.abs(o),Math.abs(s))},multiplyScalar:function(t,n,a){return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t},multiplyScalarAndAdd:function(t,n,a,r){return t[0]=n[0]+a[0]*r,t[1]=n[1]+a[1]*r,t[2]=n[2]+a[2]*r,t[3]=n[3]+a[3]*r,t},mul:c,sub:h});function M(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=a[0],s=a[1],M=a[2],f=a[3],l=a[4],v=a[5];return t[0]=r*h+e*s,t[1]=u*h+o*s,t[2]=r*M+e*f,t[3]=u*M+o*f,t[4]=r*l+e*v+i,t[5]=u*l+o*v+c,t}function f(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t[3]=n[3]-a[3],t[4]=n[4]-a[4],t[5]=n[5]-a[5],t}var l=M,v=f,b=Object.freeze({create:function(){var t=new a(6);return a!=Float32Array&&(t[1]=0,t[2]=0,t[4]=0,t[5]=0),t[0]=1,t[3]=1,t},clone:function(t){var n=new a(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},copy:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},identity:function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},fromValues:function(t,n,r,u,e,o){var i=new a(6);return i[0]=t,i[1]=n,i[2]=r,i[3]=u,i[4]=e,i[5]=o,i},set:function(t,n,a,r,u,e,o){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t[4]=e,t[5]=o,t},invert:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=a*e-r*u;return c?(c=1/c,t[0]=e*c,t[1]=-r*c,t[2]=-u*c,t[3]=a*c,t[4]=(u*i-e*o)*c,t[5]=(r*o-a*i)*c,t):null},determinant:function(t){return t[0]*t[3]-t[1]*t[2]},multiply:M,rotate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=Math.sin(a),s=Math.cos(a);return t[0]=r*s+e*h,t[1]=u*s+o*h,t[2]=r*-h+e*s,t[3]=u*-h+o*s,t[4]=i,t[5]=c,t},scale:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=a[0],s=a[1];return t[0]=r*h,t[1]=u*h,t[2]=e*s,t[3]=o*s,t[4]=i,t[5]=c,t},translate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=a[0],s=a[1];return t[0]=r,t[1]=u,t[2]=e,t[3]=o,t[4]=r*h+e*s+i,t[5]=u*h+o*s+c,t},fromRotation:function(t,n){var a=Math.sin(n),r=Math.cos(n);return t[0]=r,t[1]=a,t[2]=-a,t[3]=r,t[4]=0,t[5]=0,t},fromScaling:function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},fromTranslation:function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},str:function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},frob:function(t){return Math.hypot(t[0],t[1],t[2],t[3],t[4],t[5],1)},add:function(t,n,a){return t[0]=n[0]+a[0],t[1]=n[1]+a[1],t[2]=n[2]+a[2],t[3]=n[3]+a[3],t[4]=n[4]+a[4],t[5]=n[5]+a[5],t},subtract:f,multiplyScalar:function(t,n,a){return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*a,t[5]=n[5]*a,t},multiplyScalarAndAdd:function(t,n,a,r){return t[0]=n[0]+a[0]*r,t[1]=n[1]+a[1]*r,t[2]=n[2]+a[2]*r,t[3]=n[3]+a[3]*r,t[4]=n[4]+a[4]*r,t[5]=n[5]+a[5]*r,t},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=t[4],c=t[5],h=a[0],s=a[1],M=a[2],f=a[3],l=a[4],v=a[5];return Math.abs(r-h)<=n*Math.max(1,Math.abs(r),Math.abs(h))&&Math.abs(u-s)<=n*Math.max(1,Math.abs(u),Math.abs(s))&&Math.abs(e-M)<=n*Math.max(1,Math.abs(e),Math.abs(M))&&Math.abs(o-f)<=n*Math.max(1,Math.abs(o),Math.abs(f))&&Math.abs(i-l)<=n*Math.max(1,Math.abs(i),Math.abs(l))&&Math.abs(c-v)<=n*Math.max(1,Math.abs(c),Math.abs(v))},mul:l,sub:v});function m(){var t=new a(9);return a!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[5]=0,t[6]=0,t[7]=0),t[0]=1,t[4]=1,t[8]=1,t}function d(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=n[8],f=a[0],l=a[1],v=a[2],b=a[3],m=a[4],d=a[5],x=a[6],p=a[7],y=a[8];return t[0]=f*r+l*o+v*h,t[1]=f*u+l*i+v*s,t[2]=f*e+l*c+v*M,t[3]=b*r+m*o+d*h,t[4]=b*u+m*i+d*s,t[5]=b*e+m*c+d*M,t[6]=x*r+p*o+y*h,t[7]=x*u+p*i+y*s,t[8]=x*e+p*c+y*M,t}function x(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t[3]=n[3]-a[3],t[4]=n[4]-a[4],t[5]=n[5]-a[5],t[6]=n[6]-a[6],t[7]=n[7]-a[7],t[8]=n[8]-a[8],t}var p=d,y=x,q=Object.freeze({create:m,fromMat4:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},clone:function(t){var n=new a(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},copy:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},fromValues:function(t,n,r,u,e,o,i,c,h){var s=new a(9);return s[0]=t,s[1]=n,s[2]=r,s[3]=u,s[4]=e,s[5]=o,s[6]=i,s[7]=c,s[8]=h,s},set:function(t,n,a,r,u,e,o,i,c,h){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t[4]=e,t[5]=o,t[6]=i,t[7]=c,t[8]=h,t},identity:function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},transpose:function(t,n){if(t===n){var a=n[1],r=n[2],u=n[5];t[1]=n[3],t[2]=n[6],t[3]=a,t[5]=n[7],t[6]=r,t[7]=u}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},invert:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=n[6],h=n[7],s=n[8],M=s*o-i*h,f=-s*e+i*c,l=h*e-o*c,v=a*M+r*f+u*l;return v?(v=1/v,t[0]=M*v,t[1]=(-s*r+u*h)*v,t[2]=(i*r-u*o)*v,t[3]=f*v,t[4]=(s*a-u*c)*v,t[5]=(-i*a+u*e)*v,t[6]=l*v,t[7]=(-h*a+r*c)*v,t[8]=(o*a-r*e)*v,t):null},adjoint:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=n[6],h=n[7],s=n[8];return t[0]=o*s-i*h,t[1]=u*h-r*s,t[2]=r*i-u*o,t[3]=i*c-e*s,t[4]=a*s-u*c,t[5]=u*e-a*i,t[6]=e*h-o*c,t[7]=r*c-a*h,t[8]=a*o-r*e,t},determinant:function(t){var n=t[0],a=t[1],r=t[2],u=t[3],e=t[4],o=t[5],i=t[6],c=t[7],h=t[8];return n*(h*e-o*c)+a*(-h*u+o*i)+r*(c*u-e*i)},multiply:d,translate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=n[8],f=a[0],l=a[1];return t[0]=r,t[1]=u,t[2]=e,t[3]=o,t[4]=i,t[5]=c,t[6]=f*r+l*o+h,t[7]=f*u+l*i+s,t[8]=f*e+l*c+M,t},rotate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=n[8],f=Math.sin(a),l=Math.cos(a);return t[0]=l*r+f*o,t[1]=l*u+f*i,t[2]=l*e+f*c,t[3]=l*o-f*r,t[4]=l*i-f*u,t[5]=l*c-f*e,t[6]=h,t[7]=s,t[8]=M,t},scale:function(t,n,a){var r=a[0],u=a[1];return t[0]=r*n[0],t[1]=r*n[1],t[2]=r*n[2],t[3]=u*n[3],t[4]=u*n[4],t[5]=u*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},fromTranslation:function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},fromRotation:function(t,n){var a=Math.sin(n),r=Math.cos(n);return t[0]=r,t[1]=a,t[2]=0,t[3]=-a,t[4]=r,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},fromScaling:function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},fromMat2d:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},fromQuat:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=a+a,i=r+r,c=u+u,h=a*o,s=r*o,M=r*i,f=u*o,l=u*i,v=u*c,b=e*o,m=e*i,d=e*c;return t[0]=1-M-v,t[3]=s-d,t[6]=f+m,t[1]=s+d,t[4]=1-h-v,t[7]=l-b,t[2]=f-m,t[5]=l+b,t[8]=1-h-M,t},normalFromMat4:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=n[6],h=n[7],s=n[8],M=n[9],f=n[10],l=n[11],v=n[12],b=n[13],m=n[14],d=n[15],x=a*i-r*o,p=a*c-u*o,y=a*h-e*o,q=r*c-u*i,g=r*h-e*i,A=u*h-e*c,w=s*b-M*v,R=s*m-f*v,z=s*d-l*v,P=M*m-f*b,j=M*d-l*b,I=f*d-l*m,S=x*I-p*j+y*P+q*z-g*R+A*w;return S?(S=1/S,t[0]=(i*I-c*j+h*P)*S,t[1]=(c*z-o*I-h*R)*S,t[2]=(o*j-i*z+h*w)*S,t[3]=(u*j-r*I-e*P)*S,t[4]=(a*I-u*z+e*R)*S,t[5]=(r*z-a*j-e*w)*S,t[6]=(b*A-m*g+d*q)*S,t[7]=(m*y-v*A-d*p)*S,t[8]=(v*g-b*y+d*x)*S,t):null},projection:function(t,n,a){return t[0]=2/n,t[1]=0,t[2]=0,t[3]=0,t[4]=-2/a,t[5]=0,t[6]=-1,t[7]=1,t[8]=1,t},str:function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},frob:function(t){return Math.hypot(t[0],t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8])},add:function(t,n,a){return t[0]=n[0]+a[0],t[1]=n[1]+a[1],t[2]=n[2]+a[2],t[3]=n[3]+a[3],t[4]=n[4]+a[4],t[5]=n[5]+a[5],t[6]=n[6]+a[6],t[7]=n[7]+a[7],t[8]=n[8]+a[8],t},subtract:x,multiplyScalar:function(t,n,a){return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*a,t[5]=n[5]*a,t[6]=n[6]*a,t[7]=n[7]*a,t[8]=n[8]*a,t},multiplyScalarAndAdd:function(t,n,a,r){return t[0]=n[0]+a[0]*r,t[1]=n[1]+a[1]*r,t[2]=n[2]+a[2]*r,t[3]=n[3]+a[3]*r,t[4]=n[4]+a[4]*r,t[5]=n[5]+a[5]*r,t[6]=n[6]+a[6]*r,t[7]=n[7]+a[7]*r,t[8]=n[8]+a[8]*r,t},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]&&t[6]===n[6]&&t[7]===n[7]&&t[8]===n[8]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=t[4],c=t[5],h=t[6],s=t[7],M=t[8],f=a[0],l=a[1],v=a[2],b=a[3],m=a[4],d=a[5],x=a[6],p=a[7],y=a[8];return Math.abs(r-f)<=n*Math.max(1,Math.abs(r),Math.abs(f))&&Math.abs(u-l)<=n*Math.max(1,Math.abs(u),Math.abs(l))&&Math.abs(e-v)<=n*Math.max(1,Math.abs(e),Math.abs(v))&&Math.abs(o-b)<=n*Math.max(1,Math.abs(o),Math.abs(b))&&Math.abs(i-m)<=n*Math.max(1,Math.abs(i),Math.abs(m))&&Math.abs(c-d)<=n*Math.max(1,Math.abs(c),Math.abs(d))&&Math.abs(h-x)<=n*Math.max(1,Math.abs(h),Math.abs(x))&&Math.abs(s-p)<=n*Math.max(1,Math.abs(s),Math.abs(p))&&Math.abs(M-y)<=n*Math.max(1,Math.abs(M),Math.abs(y))},mul:p,sub:y});function g(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}function A(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=n[8],f=n[9],l=n[10],v=n[11],b=n[12],m=n[13],d=n[14],x=n[15],p=a[0],y=a[1],q=a[2],g=a[3];return t[0]=p*r+y*i+q*M+g*b,t[1]=p*u+y*c+q*f+g*m,t[2]=p*e+y*h+q*l+g*d,t[3]=p*o+y*s+q*v+g*x,p=a[4],y=a[5],q=a[6],g=a[7],t[4]=p*r+y*i+q*M+g*b,t[5]=p*u+y*c+q*f+g*m,t[6]=p*e+y*h+q*l+g*d,t[7]=p*o+y*s+q*v+g*x,p=a[8],y=a[9],q=a[10],g=a[11],t[8]=p*r+y*i+q*M+g*b,t[9]=p*u+y*c+q*f+g*m,t[10]=p*e+y*h+q*l+g*d,t[11]=p*o+y*s+q*v+g*x,p=a[12],y=a[13],q=a[14],g=a[15],t[12]=p*r+y*i+q*M+g*b,t[13]=p*u+y*c+q*f+g*m,t[14]=p*e+y*h+q*l+g*d,t[15]=p*o+y*s+q*v+g*x,t}function w(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=r+r,c=u+u,h=e+e,s=r*i,M=r*c,f=r*h,l=u*c,v=u*h,b=e*h,m=o*i,d=o*c,x=o*h;return t[0]=1-(l+b),t[1]=M+x,t[2]=f-d,t[3]=0,t[4]=M-x,t[5]=1-(s+b),t[6]=v+m,t[7]=0,t[8]=f+d,t[9]=v-m,t[10]=1-(s+l),t[11]=0,t[12]=a[0],t[13]=a[1],t[14]=a[2],t[15]=1,t}function R(t,n){return t[0]=n[12],t[1]=n[13],t[2]=n[14],t}function z(t,n){var a=n[0],r=n[1],u=n[2],e=n[4],o=n[5],i=n[6],c=n[8],h=n[9],s=n[10];return t[0]=Math.hypot(a,r,u),t[1]=Math.hypot(e,o,i),t[2]=Math.hypot(c,h,s),t}function P(t,n){var r=new a(3);z(r,n);var u=1/r[0],e=1/r[1],o=1/r[2],i=n[0]*u,c=n[1]*e,h=n[2]*o,s=n[4]*u,M=n[5]*e,f=n[6]*o,l=n[8]*u,v=n[9]*e,b=n[10]*o,m=i+M+b,d=0;return m>0?(d=2*Math.sqrt(m+1),t[3]=.25*d,t[0]=(f-v)/d,t[1]=(l-h)/d,t[2]=(c-s)/d):i>M&&i>b?(d=2*Math.sqrt(1+i-M-b),t[3]=(f-v)/d,t[0]=.25*d,t[1]=(c+s)/d,t[2]=(l+h)/d):M>b?(d=2*Math.sqrt(1+M-i-b),t[3]=(l-h)/d,t[0]=(c+s)/d,t[1]=.25*d,t[2]=(f+v)/d):(d=2*Math.sqrt(1+b-i-M),t[3]=(c-s)/d,t[0]=(l+h)/d,t[1]=(f+v)/d,t[2]=.25*d),t}function j(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t[3]=n[3]-a[3],t[4]=n[4]-a[4],t[5]=n[5]-a[5],t[6]=n[6]-a[6],t[7]=n[7]-a[7],t[8]=n[8]-a[8],t[9]=n[9]-a[9],t[10]=n[10]-a[10],t[11]=n[11]-a[11],t[12]=n[12]-a[12],t[13]=n[13]-a[13],t[14]=n[14]-a[14],t[15]=n[15]-a[15],t}var I=A,S=j,E=Object.freeze({create:function(){var t=new a(16);return a!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0),t[0]=1,t[5]=1,t[10]=1,t[15]=1,t},clone:function(t){var n=new a(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},copy:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},fromValues:function(t,n,r,u,e,o,i,c,h,s,M,f,l,v,b,m){var d=new a(16);return d[0]=t,d[1]=n,d[2]=r,d[3]=u,d[4]=e,d[5]=o,d[6]=i,d[7]=c,d[8]=h,d[9]=s,d[10]=M,d[11]=f,d[12]=l,d[13]=v,d[14]=b,d[15]=m,d},set:function(t,n,a,r,u,e,o,i,c,h,s,M,f,l,v,b,m){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t[4]=e,t[5]=o,t[6]=i,t[7]=c,t[8]=h,t[9]=s,t[10]=M,t[11]=f,t[12]=l,t[13]=v,t[14]=b,t[15]=m,t},identity:g,transpose:function(t,n){if(t===n){var a=n[1],r=n[2],u=n[3],e=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=a,t[6]=n[9],t[7]=n[13],t[8]=r,t[9]=e,t[11]=n[14],t[12]=u,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},invert:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=n[6],h=n[7],s=n[8],M=n[9],f=n[10],l=n[11],v=n[12],b=n[13],m=n[14],d=n[15],x=a*i-r*o,p=a*c-u*o,y=a*h-e*o,q=r*c-u*i,g=r*h-e*i,A=u*h-e*c,w=s*b-M*v,R=s*m-f*v,z=s*d-l*v,P=M*m-f*b,j=M*d-l*b,I=f*d-l*m,S=x*I-p*j+y*P+q*z-g*R+A*w;return S?(S=1/S,t[0]=(i*I-c*j+h*P)*S,t[1]=(u*j-r*I-e*P)*S,t[2]=(b*A-m*g+d*q)*S,t[3]=(f*g-M*A-l*q)*S,t[4]=(c*z-o*I-h*R)*S,t[5]=(a*I-u*z+e*R)*S,t[6]=(m*y-v*A-d*p)*S,t[7]=(s*A-f*y+l*p)*S,t[8]=(o*j-i*z+h*w)*S,t[9]=(r*z-a*j-e*w)*S,t[10]=(v*g-b*y+d*x)*S,t[11]=(M*y-s*g-l*x)*S,t[12]=(i*R-o*P-c*w)*S,t[13]=(a*P-r*R+u*w)*S,t[14]=(b*p-v*q-m*x)*S,t[15]=(s*q-M*p+f*x)*S,t):null},adjoint:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=n[4],i=n[5],c=n[6],h=n[7],s=n[8],M=n[9],f=n[10],l=n[11],v=n[12],b=n[13],m=n[14],d=n[15];return t[0]=i*(f*d-l*m)-M*(c*d-h*m)+b*(c*l-h*f),t[1]=-(r*(f*d-l*m)-M*(u*d-e*m)+b*(u*l-e*f)),t[2]=r*(c*d-h*m)-i*(u*d-e*m)+b*(u*h-e*c),t[3]=-(r*(c*l-h*f)-i*(u*l-e*f)+M*(u*h-e*c)),t[4]=-(o*(f*d-l*m)-s*(c*d-h*m)+v*(c*l-h*f)),t[5]=a*(f*d-l*m)-s*(u*d-e*m)+v*(u*l-e*f),t[6]=-(a*(c*d-h*m)-o*(u*d-e*m)+v*(u*h-e*c)),t[7]=a*(c*l-h*f)-o*(u*l-e*f)+s*(u*h-e*c),t[8]=o*(M*d-l*b)-s*(i*d-h*b)+v*(i*l-h*M),t[9]=-(a*(M*d-l*b)-s*(r*d-e*b)+v*(r*l-e*M)),t[10]=a*(i*d-h*b)-o*(r*d-e*b)+v*(r*h-e*i),t[11]=-(a*(i*l-h*M)-o*(r*l-e*M)+s*(r*h-e*i)),t[12]=-(o*(M*m-f*b)-s*(i*m-c*b)+v*(i*f-c*M)),t[13]=a*(M*m-f*b)-s*(r*m-u*b)+v*(r*f-u*M),t[14]=-(a*(i*m-c*b)-o*(r*m-u*b)+v*(r*c-u*i)),t[15]=a*(i*f-c*M)-o*(r*f-u*M)+s*(r*c-u*i),t},determinant:function(t){var n=t[0],a=t[1],r=t[2],u=t[3],e=t[4],o=t[5],i=t[6],c=t[7],h=t[8],s=t[9],M=t[10],f=t[11],l=t[12],v=t[13],b=t[14],m=t[15];return(n*o-a*e)*(M*m-f*b)-(n*i-r*e)*(s*m-f*v)+(n*c-u*e)*(s*b-M*v)+(a*i-r*o)*(h*m-f*l)-(a*c-u*o)*(h*b-M*l)+(r*c-u*i)*(h*v-s*l)},multiply:A,translate:function(t,n,a){var r,u,e,o,i,c,h,s,M,f,l,v,b=a[0],m=a[1],d=a[2];return n===t?(t[12]=n[0]*b+n[4]*m+n[8]*d+n[12],t[13]=n[1]*b+n[5]*m+n[9]*d+n[13],t[14]=n[2]*b+n[6]*m+n[10]*d+n[14],t[15]=n[3]*b+n[7]*m+n[11]*d+n[15]):(r=n[0],u=n[1],e=n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=n[8],f=n[9],l=n[10],v=n[11],t[0]=r,t[1]=u,t[2]=e,t[3]=o,t[4]=i,t[5]=c,t[6]=h,t[7]=s,t[8]=M,t[9]=f,t[10]=l,t[11]=v,t[12]=r*b+i*m+M*d+n[12],t[13]=u*b+c*m+f*d+n[13],t[14]=e*b+h*m+l*d+n[14],t[15]=o*b+s*m+v*d+n[15]),t},scale:function(t,n,a){var r=a[0],u=a[1],e=a[2];return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t[4]=n[4]*u,t[5]=n[5]*u,t[6]=n[6]*u,t[7]=n[7]*u,t[8]=n[8]*e,t[9]=n[9]*e,t[10]=n[10]*e,t[11]=n[11]*e,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},rotate:function(t,a,r,u){var e,o,i,c,h,s,M,f,l,v,b,m,d,x,p,y,q,g,A,w,R,z,P,j,I=u[0],S=u[1],E=u[2],O=Math.hypot(I,S,E);return O0?(r[0]=2*(c*i+M*u+h*o-s*e)/f,r[1]=2*(h*i+M*e+s*u-c*o)/f,r[2]=2*(s*i+M*o+c*e-h*u)/f):(r[0]=2*(c*i+M*u+h*o-s*e),r[1]=2*(h*i+M*e+s*u-c*o),r[2]=2*(s*i+M*o+c*e-h*u)),w(t,n,r),t},getTranslation:R,getScaling:z,getRotation:P,fromRotationTranslationScale:function(t,n,a,r){var u=n[0],e=n[1],o=n[2],i=n[3],c=u+u,h=e+e,s=o+o,M=u*c,f=u*h,l=u*s,v=e*h,b=e*s,m=o*s,d=i*c,x=i*h,p=i*s,y=r[0],q=r[1],g=r[2];return t[0]=(1-(v+m))*y,t[1]=(f+p)*y,t[2]=(l-x)*y,t[3]=0,t[4]=(f-p)*q,t[5]=(1-(M+m))*q,t[6]=(b+d)*q,t[7]=0,t[8]=(l+x)*g,t[9]=(b-d)*g,t[10]=(1-(M+v))*g,t[11]=0,t[12]=a[0],t[13]=a[1],t[14]=a[2],t[15]=1,t},fromRotationTranslationScaleOrigin:function(t,n,a,r,u){var e=n[0],o=n[1],i=n[2],c=n[3],h=e+e,s=o+o,M=i+i,f=e*h,l=e*s,v=e*M,b=o*s,m=o*M,d=i*M,x=c*h,p=c*s,y=c*M,q=r[0],g=r[1],A=r[2],w=u[0],R=u[1],z=u[2],P=(1-(b+d))*q,j=(l+y)*q,I=(v-p)*q,S=(l-y)*g,E=(1-(f+d))*g,O=(m+x)*g,T=(v+p)*A,D=(m-x)*A,F=(1-(f+b))*A;return t[0]=P,t[1]=j,t[2]=I,t[3]=0,t[4]=S,t[5]=E,t[6]=O,t[7]=0,t[8]=T,t[9]=D,t[10]=F,t[11]=0,t[12]=a[0]+w-(P*w+S*R+T*z),t[13]=a[1]+R-(j*w+E*R+D*z),t[14]=a[2]+z-(I*w+O*R+F*z),t[15]=1,t},fromQuat:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=a+a,i=r+r,c=u+u,h=a*o,s=r*o,M=r*i,f=u*o,l=u*i,v=u*c,b=e*o,m=e*i,d=e*c;return t[0]=1-M-v,t[1]=s+d,t[2]=f-m,t[3]=0,t[4]=s-d,t[5]=1-h-v,t[6]=l+b,t[7]=0,t[8]=f+m,t[9]=l-b,t[10]=1-h-M,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},frustum:function(t,n,a,r,u,e,o){var i=1/(a-n),c=1/(u-r),h=1/(e-o);return t[0]=2*e*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*e*c,t[6]=0,t[7]=0,t[8]=(a+n)*i,t[9]=(u+r)*c,t[10]=(o+e)*h,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*e*2*h,t[15]=0,t},perspective:function(t,n,a,r,u){var e,o=1/Math.tan(n/2);return t[0]=o/a,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=o,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=-1,t[12]=0,t[13]=0,t[15]=0,null!=u&&u!==1/0?(e=1/(r-u),t[10]=(u+r)*e,t[14]=2*u*r*e):(t[10]=-1,t[14]=-2*r),t},perspectiveFromFieldOfView:function(t,n,a,r){var u=Math.tan(n.upDegrees*Math.PI/180),e=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),h=2/(u+e);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=h,t[6]=0,t[7]=0,t[8]=-(o-i)*c*.5,t[9]=(u-e)*h*.5,t[10]=r/(a-r),t[11]=-1,t[12]=0,t[13]=0,t[14]=r*a/(a-r),t[15]=0,t},ortho:function(t,n,a,r,u,e,o){var i=1/(n-a),c=1/(r-u),h=1/(e-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*h,t[11]=0,t[12]=(n+a)*i,t[13]=(u+r)*c,t[14]=(o+e)*h,t[15]=1,t},lookAt:function(t,a,r,u){var e,o,i,c,h,s,M,f,l,v,b=a[0],m=a[1],d=a[2],x=u[0],p=u[1],y=u[2],q=r[0],A=r[1],w=r[2];return Math.abs(b-q)0&&(s*=l=1/Math.sqrt(l),M*=l,f*=l);var v=c*f-h*M,b=h*s-i*f,m=i*M-c*s;return(l=v*v+b*b+m*m)>0&&(v*=l=1/Math.sqrt(l),b*=l,m*=l),t[0]=v,t[1]=b,t[2]=m,t[3]=0,t[4]=M*m-f*b,t[5]=f*v-s*m,t[6]=s*b-M*v,t[7]=0,t[8]=s,t[9]=M,t[10]=f,t[11]=0,t[12]=u,t[13]=e,t[14]=o,t[15]=1,t},str:function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},frob:function(t){return Math.hypot(t[0],t[1],t[3],t[4],t[5],t[6],t[7],t[8],t[9],t[10],t[11],t[12],t[13],t[14],t[15])},add:function(t,n,a){return t[0]=n[0]+a[0],t[1]=n[1]+a[1],t[2]=n[2]+a[2],t[3]=n[3]+a[3],t[4]=n[4]+a[4],t[5]=n[5]+a[5],t[6]=n[6]+a[6],t[7]=n[7]+a[7],t[8]=n[8]+a[8],t[9]=n[9]+a[9],t[10]=n[10]+a[10],t[11]=n[11]+a[11],t[12]=n[12]+a[12],t[13]=n[13]+a[13],t[14]=n[14]+a[14],t[15]=n[15]+a[15],t},subtract:j,multiplyScalar:function(t,n,a){return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*a,t[5]=n[5]*a,t[6]=n[6]*a,t[7]=n[7]*a,t[8]=n[8]*a,t[9]=n[9]*a,t[10]=n[10]*a,t[11]=n[11]*a,t[12]=n[12]*a,t[13]=n[13]*a,t[14]=n[14]*a,t[15]=n[15]*a,t},multiplyScalarAndAdd:function(t,n,a,r){return t[0]=n[0]+a[0]*r,t[1]=n[1]+a[1]*r,t[2]=n[2]+a[2]*r,t[3]=n[3]+a[3]*r,t[4]=n[4]+a[4]*r,t[5]=n[5]+a[5]*r,t[6]=n[6]+a[6]*r,t[7]=n[7]+a[7]*r,t[8]=n[8]+a[8]*r,t[9]=n[9]+a[9]*r,t[10]=n[10]+a[10]*r,t[11]=n[11]+a[11]*r,t[12]=n[12]+a[12]*r,t[13]=n[13]+a[13]*r,t[14]=n[14]+a[14]*r,t[15]=n[15]+a[15]*r,t},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]&&t[6]===n[6]&&t[7]===n[7]&&t[8]===n[8]&&t[9]===n[9]&&t[10]===n[10]&&t[11]===n[11]&&t[12]===n[12]&&t[13]===n[13]&&t[14]===n[14]&&t[15]===n[15]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=t[4],c=t[5],h=t[6],s=t[7],M=t[8],f=t[9],l=t[10],v=t[11],b=t[12],m=t[13],d=t[14],x=t[15],p=a[0],y=a[1],q=a[2],g=a[3],A=a[4],w=a[5],R=a[6],z=a[7],P=a[8],j=a[9],I=a[10],S=a[11],E=a[12],O=a[13],T=a[14],D=a[15];return Math.abs(r-p)<=n*Math.max(1,Math.abs(r),Math.abs(p))&&Math.abs(u-y)<=n*Math.max(1,Math.abs(u),Math.abs(y))&&Math.abs(e-q)<=n*Math.max(1,Math.abs(e),Math.abs(q))&&Math.abs(o-g)<=n*Math.max(1,Math.abs(o),Math.abs(g))&&Math.abs(i-A)<=n*Math.max(1,Math.abs(i),Math.abs(A))&&Math.abs(c-w)<=n*Math.max(1,Math.abs(c),Math.abs(w))&&Math.abs(h-R)<=n*Math.max(1,Math.abs(h),Math.abs(R))&&Math.abs(s-z)<=n*Math.max(1,Math.abs(s),Math.abs(z))&&Math.abs(M-P)<=n*Math.max(1,Math.abs(M),Math.abs(P))&&Math.abs(f-j)<=n*Math.max(1,Math.abs(f),Math.abs(j))&&Math.abs(l-I)<=n*Math.max(1,Math.abs(l),Math.abs(I))&&Math.abs(v-S)<=n*Math.max(1,Math.abs(v),Math.abs(S))&&Math.abs(b-E)<=n*Math.max(1,Math.abs(b),Math.abs(E))&&Math.abs(m-O)<=n*Math.max(1,Math.abs(m),Math.abs(O))&&Math.abs(d-T)<=n*Math.max(1,Math.abs(d),Math.abs(T))&&Math.abs(x-D)<=n*Math.max(1,Math.abs(x),Math.abs(D))},mul:I,sub:S});function O(){var t=new a(3);return a!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}function T(t){var n=t[0],a=t[1],r=t[2];return Math.hypot(n,a,r)}function D(t,n,r){var u=new a(3);return u[0]=t,u[1]=n,u[2]=r,u}function F(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t}function L(t,n,a){return t[0]=n[0]*a[0],t[1]=n[1]*a[1],t[2]=n[2]*a[2],t}function V(t,n,a){return t[0]=n[0]/a[0],t[1]=n[1]/a[1],t[2]=n[2]/a[2],t}function Q(t,n){var a=n[0]-t[0],r=n[1]-t[1],u=n[2]-t[2];return Math.hypot(a,r,u)}function Y(t,n){var a=n[0]-t[0],r=n[1]-t[1],u=n[2]-t[2];return a*a+r*r+u*u}function X(t){var n=t[0],a=t[1],r=t[2];return n*n+a*a+r*r}function Z(t,n){var a=n[0],r=n[1],u=n[2],e=a*a+r*r+u*u;return e>0&&(e=1/Math.sqrt(e)),t[0]=n[0]*e,t[1]=n[1]*e,t[2]=n[2]*e,t}function _(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]}function B(t,n,a){var r=n[0],u=n[1],e=n[2],o=a[0],i=a[1],c=a[2];return t[0]=u*c-e*i,t[1]=e*o-r*c,t[2]=r*i-u*o,t}var N,k=F,U=L,W=V,C=Q,G=Y,H=T,J=X,K=(N=O(),function(t,n,a,r,u,e){var o,i;for(n||(n=3),a||(a=0),i=r?Math.min(r*n+a,t.length):t.length,o=a;o1?0:u<-1?Math.PI:Math.acos(u)},zero:function(t){return t[0]=0,t[1]=0,t[2]=0,t},str:function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=a[0],i=a[1],c=a[2];return Math.abs(r-o)<=n*Math.max(1,Math.abs(r),Math.abs(o))&&Math.abs(u-i)<=n*Math.max(1,Math.abs(u),Math.abs(i))&&Math.abs(e-c)<=n*Math.max(1,Math.abs(e),Math.abs(c))},sub:k,mul:U,div:W,dist:C,sqrDist:G,len:H,sqrLen:J,forEach:K});function tt(){var t=new a(4);return a!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0,t[3]=0),t}function nt(t){var n=new a(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n}function at(t,n,r,u){var e=new a(4);return e[0]=t,e[1]=n,e[2]=r,e[3]=u,e}function rt(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t}function ut(t,n,a,r,u){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t}function et(t,n,a){return t[0]=n[0]+a[0],t[1]=n[1]+a[1],t[2]=n[2]+a[2],t[3]=n[3]+a[3],t}function ot(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t[2]=n[2]-a[2],t[3]=n[3]-a[3],t}function it(t,n,a){return t[0]=n[0]*a[0],t[1]=n[1]*a[1],t[2]=n[2]*a[2],t[3]=n[3]*a[3],t}function ct(t,n,a){return t[0]=n[0]/a[0],t[1]=n[1]/a[1],t[2]=n[2]/a[2],t[3]=n[3]/a[3],t}function ht(t,n,a){return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t}function st(t,n){var a=n[0]-t[0],r=n[1]-t[1],u=n[2]-t[2],e=n[3]-t[3];return Math.hypot(a,r,u,e)}function Mt(t,n){var a=n[0]-t[0],r=n[1]-t[1],u=n[2]-t[2],e=n[3]-t[3];return a*a+r*r+u*u+e*e}function ft(t){var n=t[0],a=t[1],r=t[2],u=t[3];return Math.hypot(n,a,r,u)}function lt(t){var n=t[0],a=t[1],r=t[2],u=t[3];return n*n+a*a+r*r+u*u}function vt(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=a*a+r*r+u*u+e*e;return o>0&&(o=1/Math.sqrt(o)),t[0]=a*o,t[1]=r*o,t[2]=u*o,t[3]=e*o,t}function bt(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]}function mt(t,n,a,r){var u=n[0],e=n[1],o=n[2],i=n[3];return t[0]=u+r*(a[0]-u),t[1]=e+r*(a[1]-e),t[2]=o+r*(a[2]-o),t[3]=i+r*(a[3]-i),t}function dt(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]}function xt(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=a[0],c=a[1],h=a[2],s=a[3];return Math.abs(r-i)<=n*Math.max(1,Math.abs(r),Math.abs(i))&&Math.abs(u-c)<=n*Math.max(1,Math.abs(u),Math.abs(c))&&Math.abs(e-h)<=n*Math.max(1,Math.abs(e),Math.abs(h))&&Math.abs(o-s)<=n*Math.max(1,Math.abs(o),Math.abs(s))}var pt=ot,yt=it,qt=ct,gt=st,At=Mt,wt=ft,Rt=lt,zt=function(){var t=tt();return function(n,a,r,u,e,o){var i,c;for(a||(a=4),r||(r=0),c=u?Math.min(u*a+r,n.length):n.length,i=r;i=1);do{c=(e=2*r()-1)*e+(o=2*r()-1)*o}while(c>=1);var h=Math.sqrt((1-i)/c);return t[0]=n*a,t[1]=n*u,t[2]=n*e*h,t[3]=n*o*h,t},transformMat4:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3];return t[0]=a[0]*r+a[4]*u+a[8]*e+a[12]*o,t[1]=a[1]*r+a[5]*u+a[9]*e+a[13]*o,t[2]=a[2]*r+a[6]*u+a[10]*e+a[14]*o,t[3]=a[3]*r+a[7]*u+a[11]*e+a[15]*o,t},transformQuat:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=a[0],i=a[1],c=a[2],h=a[3],s=h*r+i*e-c*u,M=h*u+c*r-o*e,f=h*e+o*u-i*r,l=-o*r-i*u-c*e;return t[0]=s*h+l*-o+M*-c-f*-i,t[1]=M*h+l*-i+f*-o-s*-c,t[2]=f*h+l*-c+s*-i-M*-o,t[3]=n[3],t},zero:function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},str:function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},exactEquals:dt,equals:xt,sub:pt,mul:yt,div:qt,dist:gt,sqrDist:At,len:wt,sqrLen:Rt,forEach:zt});function jt(){var t=new a(4);return a!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t[3]=1,t}function It(t,n,a){a*=.5;var r=Math.sin(a);return t[0]=r*n[0],t[1]=r*n[1],t[2]=r*n[2],t[3]=Math.cos(a),t}function St(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=a[0],c=a[1],h=a[2],s=a[3];return t[0]=r*s+o*i+u*h-e*c,t[1]=u*s+o*c+e*i-r*h,t[2]=e*s+o*h+r*c-u*i,t[3]=o*s-r*i-u*c-e*h,t}function Et(t,n,a){a*=.5;var r=n[0],u=n[1],e=n[2],o=n[3],i=Math.sin(a),c=Math.cos(a);return t[0]=r*c+o*i,t[1]=u*c+e*i,t[2]=e*c-u*i,t[3]=o*c-r*i,t}function Ot(t,n,a){a*=.5;var r=n[0],u=n[1],e=n[2],o=n[3],i=Math.sin(a),c=Math.cos(a);return t[0]=r*c-e*i,t[1]=u*c+o*i,t[2]=e*c+r*i,t[3]=o*c-u*i,t}function Tt(t,n,a){a*=.5;var r=n[0],u=n[1],e=n[2],o=n[3],i=Math.sin(a),c=Math.cos(a);return t[0]=r*c+u*i,t[1]=u*c-r*i,t[2]=e*c+o*i,t[3]=o*c-e*i,t}function Dt(t,a,r,u){var e,o,i,c,h,s=a[0],M=a[1],f=a[2],l=a[3],v=r[0],b=r[1],m=r[2],d=r[3];return(o=s*v+M*b+f*m+l*d)<0&&(o=-o,v=-v,b=-b,m=-m,d=-d),1-o>n?(e=Math.acos(o),i=Math.sin(e),c=Math.sin((1-u)*e)/i,h=Math.sin(u*e)/i):(c=1-u,h=u),t[0]=c*s+h*v,t[1]=c*M+h*b,t[2]=c*f+h*m,t[3]=c*l+h*d,t}function Ft(t,n){var a,r=n[0]+n[4]+n[8];if(r>0)a=Math.sqrt(r+1),t[3]=.5*a,a=.5/a,t[0]=(n[5]-n[7])*a,t[1]=(n[6]-n[2])*a,t[2]=(n[1]-n[3])*a;else{var u=0;n[4]>n[0]&&(u=1),n[8]>n[3*u+u]&&(u=2);var e=(u+1)%3,o=(u+2)%3;a=Math.sqrt(n[3*u+u]-n[3*e+e]-n[3*o+o]+1),t[u]=.5*a,a=.5/a,t[3]=(n[3*e+o]-n[3*o+e])*a,t[e]=(n[3*e+u]+n[3*u+e])*a,t[o]=(n[3*o+u]+n[3*u+o])*a}return t}var Lt,Vt,Qt,Yt,Xt,Zt,_t=nt,Bt=at,Nt=rt,kt=ut,Ut=et,Wt=St,Ct=ht,Gt=bt,Ht=mt,Jt=ft,Kt=Jt,$t=lt,tn=$t,nn=vt,an=dt,rn=xt,un=(Lt=O(),Vt=D(1,0,0),Qt=D(0,1,0),function(t,n,a){var r=_(n,a);return r<-.999999?(B(Lt,Vt,n),H(Lt)<1e-6&&B(Lt,Qt,n),Z(Lt,Lt),It(t,Lt,Math.PI),t):r>.999999?(t[0]=0,t[1]=0,t[2]=0,t[3]=1,t):(B(Lt,n,a),t[0]=Lt[0],t[1]=Lt[1],t[2]=Lt[2],t[3]=1+r,nn(t,t))}),en=(Yt=jt(),Xt=jt(),function(t,n,a,r,u,e){return Dt(Yt,n,u,e),Dt(Xt,a,r,e),Dt(t,Yt,Xt,2*e*(1-e)),t}),on=(Zt=m(),function(t,n,a,r){return Zt[0]=a[0],Zt[3]=a[1],Zt[6]=a[2],Zt[1]=r[0],Zt[4]=r[1],Zt[7]=r[2],Zt[2]=-n[0],Zt[5]=-n[1],Zt[8]=-n[2],nn(t,Ft(t,Zt))}),cn=Object.freeze({create:jt,identity:function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},setAxisAngle:It,getAxisAngle:function(t,a){var r=2*Math.acos(a[3]),u=Math.sin(r/2);return u>n?(t[0]=a[0]/u,t[1]=a[1]/u,t[2]=a[2]/u):(t[0]=1,t[1]=0,t[2]=0),r},multiply:St,rotateX:Et,rotateY:Ot,rotateZ:Tt,calculateW:function(t,n){var a=n[0],r=n[1],u=n[2];return t[0]=a,t[1]=r,t[2]=u,t[3]=Math.sqrt(Math.abs(1-a*a-r*r-u*u)),t},slerp:Dt,random:function(t){var n=r(),a=r(),u=r(),e=Math.sqrt(1-n),o=Math.sqrt(n);return t[0]=e*Math.sin(2*Math.PI*a),t[1]=e*Math.cos(2*Math.PI*a),t[2]=o*Math.sin(2*Math.PI*u),t[3]=o*Math.cos(2*Math.PI*u),t},invert:function(t,n){var a=n[0],r=n[1],u=n[2],e=n[3],o=a*a+r*r+u*u+e*e,i=o?1/o:0;return t[0]=-a*i,t[1]=-r*i,t[2]=-u*i,t[3]=e*i,t},conjugate:function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},fromMat3:Ft,fromEuler:function(t,n,a,r){var u=.5*Math.PI/180;n*=u,a*=u,r*=u;var e=Math.sin(n),o=Math.cos(n),i=Math.sin(a),c=Math.cos(a),h=Math.sin(r),s=Math.cos(r);return t[0]=e*c*s-o*i*h,t[1]=o*i*s+e*c*h,t[2]=o*c*h-e*i*s,t[3]=o*c*s+e*i*h,t},str:function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},clone:_t,fromValues:Bt,copy:Nt,set:kt,add:Ut,mul:Wt,scale:Ct,dot:Gt,lerp:Ht,length:Jt,len:Kt,squaredLength:$t,sqrLen:tn,normalize:nn,exactEquals:an,equals:rn,rotationTo:un,sqlerp:en,setAxes:on});function hn(t,n,a){var r=.5*a[0],u=.5*a[1],e=.5*a[2],o=n[0],i=n[1],c=n[2],h=n[3];return t[0]=o,t[1]=i,t[2]=c,t[3]=h,t[4]=r*h+u*c-e*i,t[5]=u*h+e*o-r*c,t[6]=e*h+r*i-u*o,t[7]=-r*o-u*i-e*c,t}function sn(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t}var Mn=Nt;var fn=Nt;function ln(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=a[4],c=a[5],h=a[6],s=a[7],M=n[4],f=n[5],l=n[6],v=n[7],b=a[0],m=a[1],d=a[2],x=a[3];return t[0]=r*x+o*b+u*d-e*m,t[1]=u*x+o*m+e*b-r*d,t[2]=e*x+o*d+r*m-u*b,t[3]=o*x-r*b-u*m-e*d,t[4]=r*s+o*i+u*h-e*c+M*x+v*b+f*d-l*m,t[5]=u*s+o*c+e*i-r*h+f*x+v*m+l*b-M*d,t[6]=e*s+o*h+r*c-u*i+l*x+v*d+M*m-f*b,t[7]=o*s-r*i-u*c-e*h+v*x-M*b-f*m-l*d,t}var vn=ln;var bn=Gt;var mn=Jt,dn=mn,xn=$t,pn=xn;var yn=Object.freeze({create:function(){var t=new a(8);return a!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0,t[4]=0,t[5]=0,t[6]=0,t[7]=0),t[3]=1,t},clone:function(t){var n=new a(8);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n},fromValues:function(t,n,r,u,e,o,i,c){var h=new a(8);return h[0]=t,h[1]=n,h[2]=r,h[3]=u,h[4]=e,h[5]=o,h[6]=i,h[7]=c,h},fromRotationTranslationValues:function(t,n,r,u,e,o,i){var c=new a(8);c[0]=t,c[1]=n,c[2]=r,c[3]=u;var h=.5*e,s=.5*o,M=.5*i;return c[4]=h*u+s*r-M*n,c[5]=s*u+M*t-h*r,c[6]=M*u+h*n-s*t,c[7]=-h*t-s*n-M*r,c},fromRotationTranslation:hn,fromTranslation:function(t,n){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t[4]=.5*n[0],t[5]=.5*n[1],t[6]=.5*n[2],t[7]=0,t},fromRotation:function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=0,t[5]=0,t[6]=0,t[7]=0,t},fromMat4:function(t,n){var r=jt();P(r,n);var u=new a(3);return R(u,n),hn(t,r,u),t},copy:sn,identity:function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t[6]=0,t[7]=0,t},set:function(t,n,a,r,u,e,o,i,c){return t[0]=n,t[1]=a,t[2]=r,t[3]=u,t[4]=e,t[5]=o,t[6]=i,t[7]=c,t},getReal:Mn,getDual:function(t,n){return t[0]=n[4],t[1]=n[5],t[2]=n[6],t[3]=n[7],t},setReal:fn,setDual:function(t,n){return t[4]=n[0],t[5]=n[1],t[6]=n[2],t[7]=n[3],t},getTranslation:function(t,n){var a=n[4],r=n[5],u=n[6],e=n[7],o=-n[0],i=-n[1],c=-n[2],h=n[3];return t[0]=2*(a*h+e*o+r*c-u*i),t[1]=2*(r*h+e*i+u*o-a*c),t[2]=2*(u*h+e*c+a*i-r*o),t},translate:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=.5*a[0],c=.5*a[1],h=.5*a[2],s=n[4],M=n[5],f=n[6],l=n[7];return t[0]=r,t[1]=u,t[2]=e,t[3]=o,t[4]=o*i+u*h-e*c+s,t[5]=o*c+e*i-r*h+M,t[6]=o*h+r*c-u*i+f,t[7]=-r*i-u*c-e*h+l,t},rotateX:function(t,n,a){var r=-n[0],u=-n[1],e=-n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=i*o+s*r+c*e-h*u,f=c*o+s*u+h*r-i*e,l=h*o+s*e+i*u-c*r,v=s*o-i*r-c*u-h*e;return Et(t,n,a),r=t[0],u=t[1],e=t[2],o=t[3],t[4]=M*o+v*r+f*e-l*u,t[5]=f*o+v*u+l*r-M*e,t[6]=l*o+v*e+M*u-f*r,t[7]=v*o-M*r-f*u-l*e,t},rotateY:function(t,n,a){var r=-n[0],u=-n[1],e=-n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=i*o+s*r+c*e-h*u,f=c*o+s*u+h*r-i*e,l=h*o+s*e+i*u-c*r,v=s*o-i*r-c*u-h*e;return Ot(t,n,a),r=t[0],u=t[1],e=t[2],o=t[3],t[4]=M*o+v*r+f*e-l*u,t[5]=f*o+v*u+l*r-M*e,t[6]=l*o+v*e+M*u-f*r,t[7]=v*o-M*r-f*u-l*e,t},rotateZ:function(t,n,a){var r=-n[0],u=-n[1],e=-n[2],o=n[3],i=n[4],c=n[5],h=n[6],s=n[7],M=i*o+s*r+c*e-h*u,f=c*o+s*u+h*r-i*e,l=h*o+s*e+i*u-c*r,v=s*o-i*r-c*u-h*e;return Tt(t,n,a),r=t[0],u=t[1],e=t[2],o=t[3],t[4]=M*o+v*r+f*e-l*u,t[5]=f*o+v*u+l*r-M*e,t[6]=l*o+v*e+M*u-f*r,t[7]=v*o-M*r-f*u-l*e,t},rotateByQuatAppend:function(t,n,a){var r=a[0],u=a[1],e=a[2],o=a[3],i=n[0],c=n[1],h=n[2],s=n[3];return t[0]=i*o+s*r+c*e-h*u,t[1]=c*o+s*u+h*r-i*e,t[2]=h*o+s*e+i*u-c*r,t[3]=s*o-i*r-c*u-h*e,i=n[4],c=n[5],h=n[6],s=n[7],t[4]=i*o+s*r+c*e-h*u,t[5]=c*o+s*u+h*r-i*e,t[6]=h*o+s*e+i*u-c*r,t[7]=s*o-i*r-c*u-h*e,t},rotateByQuatPrepend:function(t,n,a){var r=n[0],u=n[1],e=n[2],o=n[3],i=a[0],c=a[1],h=a[2],s=a[3];return t[0]=r*s+o*i+u*h-e*c,t[1]=u*s+o*c+e*i-r*h,t[2]=e*s+o*h+r*c-u*i,t[3]=o*s-r*i-u*c-e*h,i=a[4],c=a[5],h=a[6],s=a[7],t[4]=r*s+o*i+u*h-e*c,t[5]=u*s+o*c+e*i-r*h,t[6]=e*s+o*h+r*c-u*i,t[7]=o*s-r*i-u*c-e*h,t},rotateAroundAxis:function(t,a,r,u){if(Math.abs(u)0){a=Math.sqrt(a);var r=n[0]/a,u=n[1]/a,e=n[2]/a,o=n[3]/a,i=n[4],c=n[5],h=n[6],s=n[7],M=r*i+u*c+e*h+o*s;t[0]=r,t[1]=u,t[2]=e,t[3]=o,t[4]=(i-r*M)/a,t[5]=(c-u*M)/a,t[6]=(h-e*M)/a,t[7]=(s-o*M)/a}return t},str:function(t){return"quat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+")"},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]&&t[2]===n[2]&&t[3]===n[3]&&t[4]===n[4]&&t[5]===n[5]&&t[6]===n[6]&&t[7]===n[7]},equals:function(t,a){var r=t[0],u=t[1],e=t[2],o=t[3],i=t[4],c=t[5],h=t[6],s=t[7],M=a[0],f=a[1],l=a[2],v=a[3],b=a[4],m=a[5],d=a[6],x=a[7];return Math.abs(r-M)<=n*Math.max(1,Math.abs(r),Math.abs(M))&&Math.abs(u-f)<=n*Math.max(1,Math.abs(u),Math.abs(f))&&Math.abs(e-l)<=n*Math.max(1,Math.abs(e),Math.abs(l))&&Math.abs(o-v)<=n*Math.max(1,Math.abs(o),Math.abs(v))&&Math.abs(i-b)<=n*Math.max(1,Math.abs(i),Math.abs(b))&&Math.abs(c-m)<=n*Math.max(1,Math.abs(c),Math.abs(m))&&Math.abs(h-d)<=n*Math.max(1,Math.abs(h),Math.abs(d))&&Math.abs(s-x)<=n*Math.max(1,Math.abs(s),Math.abs(x))}});function qn(){var t=new a(2);return a!=Float32Array&&(t[0]=0,t[1]=0),t}function gn(t,n,a){return t[0]=n[0]-a[0],t[1]=n[1]-a[1],t}function An(t,n,a){return t[0]=n[0]*a[0],t[1]=n[1]*a[1],t}function wn(t,n,a){return t[0]=n[0]/a[0],t[1]=n[1]/a[1],t}function Rn(t,n){var a=n[0]-t[0],r=n[1]-t[1];return Math.hypot(a,r)}function zn(t,n){var a=n[0]-t[0],r=n[1]-t[1];return a*a+r*r}function Pn(t){var n=t[0],a=t[1];return Math.hypot(n,a)}function jn(t){var n=t[0],a=t[1];return n*n+a*a}var In=Pn,Sn=gn,En=An,On=wn,Tn=Rn,Dn=zn,Fn=jn,Ln=function(){var t=qn();return function(n,a,r,u,e,o){var i,c;for(a||(a=2),r||(r=0),c=u?Math.min(u*a+r,n.length):n.length,i=r;i0&&(u=1/Math.sqrt(u)),t[0]=n[0]*u,t[1]=n[1]*u,t},dot:function(t,n){return t[0]*n[0]+t[1]*n[1]},cross:function(t,n,a){var r=n[0]*a[1]-n[1]*a[0];return t[0]=t[1]=0,t[2]=r,t},lerp:function(t,n,a,r){var u=n[0],e=n[1];return t[0]=u+r*(a[0]-u),t[1]=e+r*(a[1]-e),t},random:function(t,n){n=n||1;var a=2*r()*Math.PI;return t[0]=Math.cos(a)*n,t[1]=Math.sin(a)*n,t},transformMat2:function(t,n,a){var r=n[0],u=n[1];return t[0]=a[0]*r+a[2]*u,t[1]=a[1]*r+a[3]*u,t},transformMat2d:function(t,n,a){var r=n[0],u=n[1];return t[0]=a[0]*r+a[2]*u+a[4],t[1]=a[1]*r+a[3]*u+a[5],t},transformMat3:function(t,n,a){var r=n[0],u=n[1];return t[0]=a[0]*r+a[3]*u+a[6],t[1]=a[1]*r+a[4]*u+a[7],t},transformMat4:function(t,n,a){var r=n[0],u=n[1];return t[0]=a[0]*r+a[4]*u+a[12],t[1]=a[1]*r+a[5]*u+a[13],t},rotate:function(t,n,a,r){var u=n[0]-a[0],e=n[1]-a[1],o=Math.sin(r),i=Math.cos(r);return t[0]=u*i-e*o+a[0],t[1]=u*o+e*i+a[1],t},angle:function(t,n){var a=t[0],r=t[1],u=n[0],e=n[1],o=a*a+r*r;o>0&&(o=1/Math.sqrt(o));var i=u*u+e*e;i>0&&(i=1/Math.sqrt(i));var c=(a*u+r*e)*o*i;return c>1?0:c<-1?Math.PI:Math.acos(c)},zero:function(t){return t[0]=0,t[1]=0,t},str:function(t){return"vec2("+t[0]+", "+t[1]+")"},exactEquals:function(t,n){return t[0]===n[0]&&t[1]===n[1]},equals:function(t,a){var r=t[0],u=t[1],e=a[0],o=a[1];return Math.abs(r-e)<=n*Math.max(1,Math.abs(r),Math.abs(e))&&Math.abs(u-o)<=n*Math.max(1,Math.abs(u),Math.abs(o))},len:In,sub:Sn,mul:En,div:On,dist:Tn,sqrDist:Dn,sqrLen:Fn,forEach:Ln});t.glMatrix=e,t.mat2=s,t.mat2d=b,t.mat3=q,t.mat4=E,t.quat=cn,t.quat2=yn,t.vec2=Vn,t.vec3=$,t.vec4=Pt,Object.defineProperty(t,"__esModule",{value:!0})});
29 |
--------------------------------------------------------------------------------
/assets/include.math:
--------------------------------------------------------------------------------
1 | 123+46 x (456 + 4 * 4 + 5)
2 | y := x
3 | x := 5
4 | ( a ; b ) := ( 1 ; 2 )
5 | (b;a) := (a;b)
6 | 123+46 x (456 + 4 * 4 + 5)
7 |
--------------------------------------------------------------------------------
/assets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | OCalc
7 |
15 |
16 |
17 |
18 |
19 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/assets/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const http = require('http');
3 | const url = require('url');
4 | const v = require("./package.json").version;
5 |
6 | let serve_file = res => file => fs.open(file, 'r', 0o444, function(err, fd) {
7 | if (err) {
8 | res.writeHead(404);
9 | fs.createReadStream("404.html").pipe(res);
10 | } else {
11 | res.writeHead(200);
12 | fs.createReadStream(null, {
13 | fd
14 | }).pipe(res);
15 | }
16 | });
17 |
18 | let is_main_page = url => /^\/(?:(?:index|main)(?:\.(?:(?:ht)?ml|js))?)?$/.test(url);
19 |
20 | let is_release = url => /\/releases?/.test(url);
21 |
22 | let match_only_version = url => url.match(/^\/(?:[vV]?(?(?0|[1-9]\d*)(?:\.(?0|[1-9]\d*)(?:\.(?0|[1-9]\d*))?)?)|(?last|latest))$/);
23 |
24 | let match_correct_path = url => url.match(/^\/(?:[vV]?(?(?0|[1-9]\d*)(?:\.(?0|[1-9]\d*)(?:\.(?0|[1-9]\d*))?)?)|(?last|latest))(?\/[^\/]*)?$/);
25 |
26 | let list_version = res => {
27 | console.log("releases");
28 | serve_file(res)("index.html");
29 | };
30 |
31 | let server = http.createServer(function(req, res) {
32 | let u = url.parse(req.url);
33 | var match;
34 |
35 | if (u.search)
36 | console.error(res.connection.remoteAddress, res.connection.remotePort, req.url);
37 |
38 | if (is_main_page(u.pathname)) {
39 | console.log("is_main_page: index");
40 | serve_file(res)("index.html");
41 | } /*else if (is_release(u.pathname)) {
42 | console.log("is_release: list versions");
43 | list_version(res);
44 | // TO BE COMPLETED
45 | } */else if ((match = match_only_version(u.pathname))) {
46 | var {groups: {major = '0', minor = '0', patch = '0', shorcut}} = match;
47 | console.log("match_version: redirect ", match.groups.version, "or", match.groups.shorcut, "to", `${major}.${minor}.${patch}/`);
48 | switch (shorcut)
49 | {
50 | case "latest":
51 | case "last":
52 | res.writeHead(302, {
53 | "Location": v + "/"
54 | });
55 | break;
56 | default:
57 | res.writeHead(301, {
58 | "Location": `${major}.${minor}.${patch}/`
59 | });
60 | break;
61 | }
62 | res.end();
63 | } else if ((match = match_correct_path(u.pathname))) {
64 | var folder = undefined;
65 | var {groups: {major = '0', minor = '0', patch = '0', shorcut, rest}} = match;
66 | switch (shorcut)
67 | {
68 | case "latest":
69 | case "last":
70 | folder = v;
71 | break;
72 | default:
73 | folder = `${major}.${minor}.${patch}`;
74 | // add the .0 if needed
75 | break;
76 | }
77 | console.log("match_correct_path: folder :", folder);
78 | var new_path;
79 | if (is_main_page(rest))
80 | new_path = folder + "/index.html";
81 | else
82 | new_path = folder + "/" + rest.split('/').pop();
83 | console.log("match_correct_path: ", new_path);
84 | serve_file(res)(new_path);
85 | } else {
86 | var new_path = u.pathname.split('/').pop();
87 | console.log("fallback", new_path);// by default we look at current directory
88 | serve_file(res)(new_path);
89 | }
90 | }).listen(80);
91 |
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/logo.png
--------------------------------------------------------------------------------
/assets/pi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/assets/pi.png
--------------------------------------------------------------------------------
/create-release.sh:
--------------------------------------------------------------------------------
1 | mkdir -p bin
2 | cp $cur__bin/* bin
3 | echo "<3"
4 |
--------------------------------------------------------------------------------
/dune:
--------------------------------------------------------------------------------
1 | (env
2 | (dev
3 | (flags
4 | (:standard -w -42 -warn-error -A)))
5 | (release
6 | (flags
7 | (:standard -O3))))
8 |
9 | (install
10 | (section bin)
11 | (package OCalc)
12 | (files
13 | package.json))
14 |
--------------------------------------------------------------------------------
/dune-project:
--------------------------------------------------------------------------------
1 | (lang dune 1.7)
2 | (version dev)
3 | (using fmt 1.1)
4 |
--------------------------------------------------------------------------------
/equation.ml:
--------------------------------------------------------------------------------
1 | let lire_sys nom_fichier =
2 | let nom_fichier = open_in nom_fichier in
3 | let rec boucle acc =
4 | try
5 | let s = input_line nom_fichier in
6 | let s = String.split_on_char '\t' s in
7 | let s = Array.of_list s in
8 | boucle (s :: acc)
9 | with End_of_file ->
10 | let () = close_in nom_fichier in
11 | match List.rev acc with
12 | [] -> failwith "pas assez de ligne"
13 | | e :: l -> l |> Array.of_list, e
14 | in let mat, inc = boucle [] in
15 | let w = Array.length inc in
16 | let mat = Array.map (function ligne -> Array.map float_of_string ligne) mat in
17 | let h = Array.length mat in
18 | mat, w, h, inc
19 |
20 | let addition_ligne ligne lignej =
21 | Array.mapi (fun i -> (+.) lignej.(i)) ligne
22 |
23 | let multiplication_ligne ligne j =
24 | Array.mapi (fun _ e -> e *. j) ligne
25 |
26 | let comb_lineaire mat (a, i) (b, j) =
27 | Array.mapi (fun k e -> a *. e +. b *. mat.(j).(k)) mat.(i)
28 |
29 | let echanger_ligne mat i j =
30 | let l = mat.(i) in
31 | let () = mat.(i) <- mat.(j) in
32 | mat.(j) <- l
33 |
34 | let ajouter_ligne mat i w h =
35 | let l = Array.make (w + 1) 0. in
36 | let () = l.(i) <- 1. in
37 | let () = l.(w) <- 1. in
38 | let () = mat := Array.append !mat [| l |] in
39 | incr h
40 |
41 | (** check if zero for the float*)
42 | let zero a =
43 | -0.0001 < a && a < 0.0001
44 |
45 | (** print unkwon and coefficient*)
46 | let print_mat inc mat =
47 | let () = Array.iter (Printf.printf "%.8s ") inc in
48 | let () = print_endline "" in
49 | Array.iter (fun l ->
50 | let () = Array.iter (Printf.printf "%.6f ") l in
51 | print_endline ""
52 | ) !mat
53 |
54 | let triangle_superieur (* inc *) mat h w =
55 | let mat = ref mat
56 | and h = ref h in
57 | let () =
58 | for i = 0 to pred w do
59 | (*let () = Printf.printf "on traite la colonne i: %d\n" i in*)
60 | let () =
61 | if i > pred !h then
62 | (*let () = Printf.printf "il nous manque une ligne\n" in
63 | let () = *)ajouter_ligne mat i w h
64 | (*in print_mat inc mat*)
65 | in let () =
66 | if zero !mat.(i).(i) then
67 | (*let () = Printf.printf "notre pivot est nul\n" in*)
68 | let () =
69 | for k = i + 1 to pred !h do
70 | if not (zero !mat.(k).(i)) then
71 | echanger_ligne !mat i i
72 | done
73 | in(* let () = print_mat inc mat in*)
74 | if zero !mat.(i).(i) then
75 | (*let () = Printf.printf "on n'a pas de remplacant\n" in*)
76 | let () = ajouter_ligne mat i w h in
77 | (*let () = *)echanger_ligne !mat (pred !h) i(* in
78 | print_mat inc mat*)
79 | in for j = i + 1 to pred !h do
80 | (*let () = Printf.printf "on traite la ligne j: %d\n" j in
81 | let () = print_mat inc mat in
82 | let () =*)
83 | !mat.(j) <- comb_lineaire !mat (!mat.(j).(i), i) (~-. (!mat.(i).(i)), j)
84 | (*in print_mat inc mat*)
85 | done
86 | done
87 | in !mat, !h
88 |
89 | let nomalise (* inc *) mat w =
90 | let () =
91 | for i = 0 to pred w do
92 | (*let () =
93 | Printf.printf "On reduit la ligne i: %d selon le pivot (%d, %d): %f\n"
94 | i i i mat.(i).(i)
95 | in let () = *)mat.(i) <- multiplication_ligne mat.(i) (1. /. mat.(i).(i))(* in
96 | print_mat inc (ref mat)*)
97 | done
98 | in mat
99 |
100 | let remonte (* inc *) mat w =
101 | let () =
102 | for i = pred w downto 0 do
103 | for k = i - 1 downto 0 do
104 | (*let () = Printf.printf "i: %d, k: %d, val: %f, val: %f\n" i k (mat.(i).(i)) (mat.(k).(i)) in
105 | let () = *)mat.(k) <- comb_lineaire mat (~-.(mat.(k).(i)), i) (mat.(i).(i), k)(* in
106 | print_mat inc (ref mat)*)
107 | done
108 | done
109 | in mat
110 |
111 | let contractition_presente mat w h =
112 | let resultat = ref false in
113 | let () =
114 | for i = w to pred h do
115 | (*let () = Printf.printf "i: %d, w: %d\n" i w in*)
116 | resultat := not (Float.classify_float mat.(i).(w) = Float.FP_zero) || !resultat
117 | done
118 | in !resultat
119 |
120 | let sauvegarder_resultat mat w h inc fichier =
121 | let fichier = open_out fichier in
122 | let () =
123 | if contractition_presente mat w h then
124 | output_string fichier "il y a une contractition presente\n"
125 | else
126 | Array.iteri (fun i e -> Printf.fprintf fichier "%s = %f\n" e mat.(i).(w)) inc in
127 | close_out fichier
128 |
129 | let resoudre_sys mat w h inc =
130 | let mat, h = triangle_superieur (* inc *) mat h w in
131 | let mat = nomalise (* inc *) mat w in
132 | let mat = remonte (* inc *) mat w in
133 | mat, w, h, inc;;
134 |
135 | let resoudre_sys_depuis_fichier nom_fichier sortie_fichier =
136 | let mat, w, h, inc = lire_sys nom_fichier in
137 | (*let () = Printf.printf "On a lu le systeme et on a w: %d, h: %d\n" w h in*)
138 | let mat, w, h, inc = resoudre_sys mat w h inc in
139 | sauvegarder_resultat mat w h inc sortie_fichier
140 |
141 | (** examples files*)
142 | let res = resoudre_sys_depuis_fichier "equation0.equ" "solution0.res";;
143 | let res = resoudre_sys_depuis_fichier "equation1.equ" "solution1.res";;
144 | let res = resoudre_sys_depuis_fichier "equation2.equ" "solution2.res";;
145 | let res = resoudre_sys_depuis_fichier "equation3.equ" "solution3.res";;
146 | let res = resoudre_sys_depuis_fichier "equation4.equ" "solution4.res";;
147 | let res = resoudre_sys_depuis_fichier "equation5.equ" "solution5.res";;
148 | let res = resoudre_sys_depuis_fichier "equation6.equ" "solution6.res";;
149 |
--------------------------------------------------------------------------------
/equation0.equ:
--------------------------------------------------------------------------------
1 | x y z
2 | 1 1 0 4
3 | 2 2 5 6
4 |
--------------------------------------------------------------------------------
/equation1.equ:
--------------------------------------------------------------------------------
1 | x y z
2 | 1 1 0 4
3 | 2 0 5 6
4 |
--------------------------------------------------------------------------------
/equation2.equ:
--------------------------------------------------------------------------------
1 | x y z
2 | 1 1 0 4
3 | 0 2 5 6
4 |
--------------------------------------------------------------------------------
/equation3.equ:
--------------------------------------------------------------------------------
1 | x y z
2 | 1 1 0 4
3 | 0 2 5 6
4 | 1 5 2 1
5 | 7 8 9 5
6 |
--------------------------------------------------------------------------------
/equation4.equ:
--------------------------------------------------------------------------------
1 | x y z
2 | 0 1 1 4
3 | 5 2 0 6
4 | 2 5 1 1
5 | 9 8 7 5
6 |
--------------------------------------------------------------------------------
/equation5.equ:
--------------------------------------------------------------------------------
1 | x y z a
2 | 0 1 1 0 4
3 | 5 2 0 0 6
4 | 2 5 1 0 1
5 | 9 8 7 0 5
6 |
--------------------------------------------------------------------------------
/equation6.equ:
--------------------------------------------------------------------------------
1 | x y z
2 | 3 1 2 13
3 | 1 2 3 13
4 | 1 1 1 6
5 | 2 2 2 12
6 |
--------------------------------------------------------------------------------
/matrix.ml:
--------------------------------------------------------------------------------
1 | module type Value = sig
2 | type t
3 |
4 | val zero : t
5 | val unit : t
6 | val neg : t -> t
7 | val additioner : t -> t -> t
8 | val soustraire : t -> t -> t
9 | val diviser : t -> t -> t
10 | val multiplier : t -> t -> t
11 | val print : t -> unit
12 | end
13 |
14 | module Generic_matrix (V : Value) = struct
15 | type t = V.t array array
16 |
17 | let print = V.print
18 | let init n p = Array.make_matrix n p V.zero
19 | let __protect m = Array.length m > 0 && Array.length m.(0) > 0
20 | let size m =
21 | let h = Array.length m in
22 | if h = 0 then
23 | h, 0
24 | else
25 | h, Array.length m.(0)
26 | let foreach ?(line = function _ -> ()) m f =
27 | if __protect m then
28 | let h, w = size m in
29 | for i = 0 to pred h do
30 | let () =
31 | for j = 0 to pred w do
32 | f i j m.(i).(j)
33 | done
34 | in line m.(i)
35 | done
36 | let print m =
37 | let () =
38 | foreach ~line:(fun _ -> print_char '\n') m (fun _ _ -> V.print)
39 | in print_char '\n'
40 | let foreach2 f m1 m2 =
41 | let (h, w) = size m1 in
42 | if (h, w) = size m2 then
43 | let mres = init h w in
44 | let () = foreach m1 (fun i j e -> mres.(i).(j) <- f e m2.(i).(j)) in
45 | mres
46 | else
47 | failwith (I18n.matrice_mauvaise_dimension ())
48 | let __vide_vers_identite m =
49 | let h, w = size m in
50 | let () =
51 | for i = 0 to pred (min h w) do
52 | m.(i).(i) <- V.unit
53 | done
54 | in m
55 | let identite n =
56 | let mres = init n n in
57 | __vide_vers_identite mres
58 | let additioner m1 m2 = foreach2 V.additioner m1 m2
59 | let soustraire m1 m2 = foreach2 V.soustraire m1 m2
60 | let multiplier m1 m2 =
61 | let (n, p) = size m1
62 | and (p', q) = size m2 in
63 | if p = p' then
64 | let mres = init n n in
65 | let prod_ligne_colonne i j =
66 | let res = ref V.zero in
67 | let () =
68 | for k = 0 to pred p do
69 | res := V.additioner !res (V.multiplier m1.(i).(k) m2.(k).(j))
70 | done
71 | in !res
72 | in let () = foreach mres (fun i j _ -> mres.(i).(j) <- prod_ligne_colonne i j) in
73 | mres
74 | else
75 | failwith (I18n.matrice_mauvaise_dimension ())
76 | let multiplier_scalaire m scalaire =
77 | let (h, w) = size m in
78 | let mres = init h w in
79 | let () = foreach m (fun i j e -> mres.(i).(j) <- V.multiplier e scalaire) in
80 | mres
81 | module Operation_elementaires = struct
82 | let multiplier_ligne l scalaire =
83 | Array.map (V.multiplier scalaire) l
84 | let additioner_ligne l1 l2 =
85 | Array.mapi (fun k -> V.additioner l2.(k)) l1
86 | let neg_ligne l =
87 | Array.map V.neg l
88 | let echanger_ligne m i j =
89 | let tmp = m.(i) in
90 | let () = m.(i) <- m.(j) in
91 | m.(j) <- tmp
92 | let affecter_ligne m i l =
93 | m.(i) <- l
94 | end
95 | let inverser m' =
96 | let h, w = size m' in
97 | let m = init h w in
98 | let () = foreach m' (fun i j e -> m.(i).(j) <- e) in
99 | let n = min h w in
100 | let mres = init w h in
101 | let mres = __vide_vers_identite mres in
102 | let open Operation_elementaires in
103 | let () =
104 | for i = 0 to pred (pred n) do
105 | for j = i + 1 to pred h do
106 | if m.(j).(i) <> V.zero then
107 | (* let () = *)
108 | if m.(i).(i) = V.zero then
109 | let () = echanger_ligne m j i in
110 | echanger_ligne mres j i
111 | else
112 | let pivot = m.(i).(i) in
113 | let coeff = V.diviser m.(j).(i) pivot in
114 | let modifier_ligne m =
115 | let ligne = multiplier_ligne m.(i) coeff in
116 | let ligne = neg_ligne ligne in
117 | let ligne = additioner_ligne m.(j) ligne in
118 | affecter_ligne m j ligne
119 | in let () = modifier_ligne m in
120 | if j < n then
121 | modifier_ligne mres
122 | (* in fact we should empty it *)
123 | (*in print mres*)
124 | done
125 | done
126 | in let () = print m in
127 | let () = print_char '\n' in
128 | let () = print_char '\n' in
129 | mres
130 |
131 | end
132 |
133 | module Test = struct
134 | type t = int
135 |
136 | let zero = 0
137 | let unit = 1
138 | let neg = ( ~- )
139 | let additioner = ( + )
140 | let soustraire = ( - )
141 | let diviser = ( / )
142 | let multiplier = ( * )
143 | let print = Printf.printf "%5d"
144 | end
145 |
146 | module Test_matrix = Generic_matrix(Test)
147 |
148 | module Test_float = struct
149 | type t = float
150 |
151 | let zero = 0.
152 | let unit = 1.
153 | let neg = ( ~-. )
154 | let additioner = ( +. )
155 | let soustraire = ( -. )
156 | let diviser = ( /. )
157 | let multiplier = ( *. )
158 | let print = Printf.printf "%10.6f"
159 | end
160 |
161 | module Test_float_matrix = Generic_matrix(Test_float)
162 |
163 | let m1 =
164 | [|
165 | [|1; 2; 3|];
166 | [|4; 5; 6|];
167 | [|7; 8; 9|];
168 | |]
169 |
170 | let m2 =
171 | [|
172 | [|9; 8; 7|];
173 | [|6; 5; 4|];
174 | [|3; 2; 1|];
175 | |]
176 |
177 | let m3 =
178 | [|
179 | [|6.; 6.; 6.|];
180 | [|4.; 7.; 6.|];
181 | [|6.; 4.; 6.|];
182 | (*[|6.; 4.; 6.|];(* for test *)
183 | [|6.; 4.; 5.|];(* for test *)
184 | [|6.; 4.; 6.|];(* for test *) *)
185 | |]
186 |
187 | let inv_m3 =
188 | [|
189 | [|9. ; -6.; -3.|];
190 | [|6. ; 0.; -6.|];
191 | [|-13.; 6.; 9.|];
192 | |]
193 |
194 | (*
195 | let i3 = Test_matrix.identite 3
196 | let res1 = Test_matrix.additioner m1 m2
197 | let res2 = Test_matrix.soustraire res1 m2
198 | let res3 = Test_matrix.multiplier i3 m1*)
199 | let res4 = Test_float_matrix.inverser m3
200 | (*
201 | let () = Test_float_matrix.print
202 | (Test_float_matrix.multiplier_scalaire inv_m3 (1. /. 12.))
203 | let () = Test_float_matrix.print (Test_float_matrix.multiplier res4 m3)
204 | *)
205 |
206 | (*
207 | let () = Test_matrix.print i3
208 | let () = Test_matrix.print m1
209 | let () = Test_matrix.print res1
210 | let () = Test_matrix.print res2
211 | let () = Test_matrix.print res3
212 | *)
213 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ocalc",
3 | "version": "0.5.1",
4 | "description": "A formal calculator written in OCaml",
5 | "main": "index.js",
6 | "esy": {
7 | "build": [
8 | "dune build OCalc.install",
9 | "refmterr dune build src/interfaces/topCmd.exe",
10 | "refmterr dune build src/interfaces/topTest.exe",
11 | "refmterr dune build src/interfaces/topGui.exe"
12 | ],
13 | "install": [
14 | "esy-installer OCalc.install"
15 | ]
16 | },
17 | "dependencies": {
18 | "ejs": "^2.6.1"
19 | },
20 | "devDependencies": {
21 | "@esy-ocaml/reason": "3.4.0",
22 | "reason-glfw": "^3.2.1024",
23 | "reason-fontkit": "^2.4.0",
24 | "reason-gl-matrix": "^0.9.9304",
25 | "rebez": "*",
26 | "revery": "*",
27 | "@opam/color": "^0.2.0",
28 | "@opam/js_of_ocaml": "*",
29 | "@opam/js_of_ocaml-compiler": "*",
30 | "@opam/js_of_ocaml-lwt": "*",
31 | "@opam/lwt": "^4.0.0",
32 | "@opam/lwt_ppx": "^1.1.0",
33 | "@brisk/brisk-reconciler": "*",
34 | "flex": "^1.2.2",
35 | "reperf": "^1.4.0",
36 | "@reason-native/console": "^0.0.3",
37 | "ocaml": "^4.7.0",
38 | "@opam/dune": "^1.5.0",
39 | "@opam/odoc": "*",
40 | "@opam/yojson": "^1.7.0",
41 | "@opam/lambda-term": "1.13",
42 | "minesweeper": "*"
43 | },
44 | "resolutions": {
45 | "@opam/dune": "1.7.3",
46 | "rebez": "github:jchavarri/rebez#46cbc183",
47 | "@opam/cmdliner": "1.0.2",
48 | "@opam/js_of_ocaml": "github:ocsigen/js_of_ocaml:js_of_ocaml.opam#db257ce",
49 | "@opam/js_of_ocaml-compiler": "github:ocsigen/js_of_ocaml:js_of_ocaml-compiler.opam#db257ce",
50 | "@brisk/brisk-reconciler": "github:briskml/brisk-reconciler#dd933fc",
51 | "revery": "github:revery-ui/revery#ea61525eb266b8c7b478558bad5686acdccc10c4",
52 | "minesweeper": "github:Et7f3/minesweeper#6bb8fde5b4556f7b209ad85cb8aba66b480d6dc6"
53 | },
54 | "scripts": {
55 | "test": "echo \"Error: no test specified\" && exit 1",
56 | "build": "esy b",
57 | "build:release": "esy b dune build --profile=release --root . -j4",
58 | "build:js": "esy b dune build examples/Examples.bc.js",
59 | "build:js:release": "esy b dune build examples/Examples.bc.js",
60 | "revery-test": "esy b dune runtest",
61 | "format": "esy dune build @fmt --auto-promote",
62 | "format:windows": "esy b .ci/format.sh",
63 | "doc": "refmterr esy dune build @doc --root .",
64 | "create-release": "bash ./create-release.sh",
65 | "run": "esy x OCalc #{self.bin}/include.math"
66 | },
67 | "repository": {
68 | "type": "git",
69 | "url": "ocal.github"
70 | },
71 | "keywords": [
72 | "formal",
73 | "calculator",
74 | "ocaml"
75 | ],
76 | "maintainers": [
77 | "elie.brami",
78 | "alexandre.mourgues",
79 | "gautier.habermann",
80 | "quentin.feugueur"
81 | ],
82 | "license": "ISC"
83 | }
84 |
--------------------------------------------------------------------------------
/src/interfaces/commune.ml:
--------------------------------------------------------------------------------
1 | let argv = Sys.argv
2 | let argc = Array.length argv
3 | let api_url = "https://api.github.com/repos/Et7f3/ocalc/releases"
4 |
5 | let liste_historique = ref []
6 |
7 | let evaluer_fichier fichier contexte =
8 | if Revery.Environment.webGL then
9 | contexte
10 | else
11 | if Filename.check_suffix fichier ".math" then
12 | try
13 | let fichier = open_in fichier in
14 | let rec boucle f =
15 | try
16 | let entree = input_line fichier in
17 | let sortie, f =
18 | try
19 | Noyau.Moteur.evaluate_with_history entree f
20 | with Division_by_zero -> (I18n.division_par_zero ()), f
21 | in let hist = Printf.sprintf "%s = %s" entree sortie in
22 | let () = liste_historique := hist :: !liste_historique in
23 | let () = print_endline hist in
24 | let () = flush stdout in
25 | boucle f
26 | with End_of_file ->
27 | let () = close_in fichier in
28 | f
29 | in boucle contexte
30 | with Sys_error _ ->
31 | let () = prerr_endline (I18n.fichier_inexistant fichier) in
32 | contexte
33 | else
34 | let () = prerr_endline (I18n.fichier_pas_math fichier) in
35 | contexte
36 |
37 | let init_context =
38 | if Revery.Environment.webGL then
39 | Noyau.Moteur.empty_context
40 | else
41 | let evaluate_arg f max =
42 | let rec evaluate_arg f i =
43 | if i = max then
44 | let () = flush stdout in
45 | let () = flush stderr in
46 | f
47 | else
48 | let f = evaluer_fichier Sys.argv.(i) f in
49 | evaluate_arg f (i + 1)
50 | in evaluate_arg f 1
51 | in evaluate_arg Noyau.Moteur.empty_context (Array.length Sys.argv)
52 |
53 | (*
54 | let ip = Unix.((gethostbyname "localhost").h_addr_list.(0))
55 | let addr = Unix.ADDR_INET (ip, 80)
56 |
57 | let s =
58 | "GET /repos/Et7f3/ocalc/releases HTTP/1.1\r\n\
59 | Host: api.github.com\r\n\
60 | User-Agent: OCaml\r\n\
61 | Connection: close\r\n\
62 | \r\n"
63 |
64 | let sock = Unix.(socket PF_INET SOCK_STREAM 0)
65 | let _ = Unix.connect sock addr
66 |
67 | let in_ch = Unix.in_channel_of_descr sock
68 | let out_ch = Unix.out_channel_of_descr sock
69 |
70 |
71 |
72 | let _ =
73 | output_string out_ch
74 | s;
75 | flush out_ch
76 |
77 |
78 |
79 | let g =
80 | try
81 | let () = while input_line in_ch <> "\r"; do () done in
82 | Yojson.Basic.from_channel in_ch
83 | with End_of_file ->
84 | let () = Unix.close sock in
85 | Yojson.Basic.from_string "[]";;
86 |
87 | match g with
88 | `List l -> List.iter (function g -> Printf.printf "%s\n\n" (Yojson.Basic.to_string g)) l
89 | | _ -> print_endline "can't load versions"
90 | *)
91 |
--------------------------------------------------------------------------------
/src/interfaces/dune:
--------------------------------------------------------------------------------
1 | (library
2 | (name Commune)
3 | (modules Commune)
4 | (libraries Yojson Revery Noyau))
5 |
6 | (executable
7 | (name topCmd)
8 | (modules TopCmd)
9 | (public_name topCmd)
10 | (package OCalc)
11 | (libraries Commune Noyau I18n))
12 |
13 | (executable
14 | (name topTest)
15 | (modules TopTest)
16 | (public_name topTest)
17 | (package OCalc)
18 | (libraries Commune Noyau))
19 |
20 | (executable
21 | (name topGui)
22 | (modules TopGui)
23 | (public_name OCalc)
24 | (package OCalc)
25 | (libraries js_of_ocaml Revery Commune Noyau Minesweeper.lib))
26 |
--------------------------------------------------------------------------------
/src/interfaces/topCmd.ml:
--------------------------------------------------------------------------------
1 | let corp_principal contexte =
2 | let ps1 = "# " in
3 | let () = print_endline (I18n.bienvenue ()) in
4 | let () = print_endline (I18n.sortir_msg ()) in
5 | let rec evalue_en_boucle ancienne_ligne contexte =
6 | let () = print_string ps1 in
7 | let ligne = ancienne_ligne ^ read_line () in
8 | if Filename.check_suffix ligne ";;" then
9 | let ligne =
10 | let taille = String.length ligne - 2 in
11 | String.sub ligne 0 taille
12 | in
13 | if ligne <> I18n.sortir_1 () || ligne <> I18n.sortir_2 () then
14 | let sortie, contexte =
15 | if Noyau.Utils.parenthese_correcte ligne then
16 | try
17 | Noyau.Moteur.evaluate_with_history ligne contexte
18 | with Division_by_zero -> (I18n.division_par_zero ()), contexte
19 | else
20 | I18n.mauvais_parenthesage (), contexte
21 | in let () = print_endline sortie in
22 | evalue_en_boucle "" contexte
23 | else
24 | evalue_en_boucle ligne contexte
25 | in evalue_en_boucle "" contexte
26 | in corp_principal Commune.init_context
27 |
--------------------------------------------------------------------------------
/src/interfaces/topCmd.mli:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topCmd.mli
--------------------------------------------------------------------------------
/src/interfaces/topFichiers.ml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topFichiers.ml
--------------------------------------------------------------------------------
/src/interfaces/topFichiers.mli:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topFichiers.mli
--------------------------------------------------------------------------------
/src/interfaces/topGui.ml:
--------------------------------------------------------------------------------
1 | open Revery
2 | open Revery.UI
3 | open Revery.UI.Components
4 |
5 |
6 | let bgColor =
7 | (*if Environment.webGL then
8 | Color.hex("#ffffff")
9 | else*)
10 | Color.hex("#212733")
11 |
12 | let _ (* txtColor *) =
13 | (*if Environment.webGL then
14 | Color.rgb 0. 0. 0.
15 | else*)
16 | Color.rgb 255. 255. 255.
17 |
18 | type vue =
19 | [
20 | `VueCalcul
21 | | `VueHistorique
22 | | `VueMatrice
23 | | `VueAccueil
24 | | `VueEquation
25 | | `VueBonus
26 | ]
27 |
28 | (*
29 | type vue_par_defaut_state =
30 | {
31 | nothing: unit;
32 | }
33 | *)
34 | type calcul_state =
35 | {
36 | valeur: string;
37 | res: string;
38 | liste_historique: string list;
39 | context: Noyau.Moteur.context;
40 | }
41 |
42 | type historique_state =
43 | {
44 | mutable liste: string list;
45 | }
46 |
47 | type matrice_mode =
48 | [
49 | `Solveur
50 | | `Addition
51 | | `Soustraction
52 | | `Multiplication
53 | | `Inverse
54 | ]
55 |
56 | type matrice_state =
57 | {
58 | mode: matrice_mode;
59 | mutable matrice1: string array array;
60 | mutable matrice2: string array array;
61 | mutable matrice_res: string array array;
62 | mutable taille1: int * int;
63 | mutable taille2: int * int;
64 | mutable taille_res: int * int;
65 | message: string;
66 | }
67 |
68 | type equation_state =
69 | {
70 | (*
71 | mutable inconnu: string list;
72 | mutable nbr_inc: int;
73 | mutable lines: int;
74 | mutable mat1: string array array;
75 | mutable mat2: string array array;
76 | res: string;
77 | *)
78 | inconnues: string array;
79 | nbr_inc: int;
80 | coef: string array array;
81 | nbr_ligne: int;
82 | resultat: Noyau.Moteur.Expr_matrix.solution_equation option
83 | }
84 |
85 | type accueil_state =
86 | {
87 | lang : I18n.lang;
88 | }
89 |
90 | type application_state =
91 | {
92 | vue_courante: vue;
93 | }
94 |
95 | type application_sauvegarde =
96 | {
97 | calcul: calcul_state;
98 | equation: equation_state;
99 | historique: historique_state;
100 | matrice: matrice_state;
101 | accueil: accueil_state;
102 | }
103 |
104 | (*
105 | module VueParDefaut = struct
106 | let component = React.component "VueParDefaut"
107 |
108 | type action = Nope
109 |
110 | let reducer action etat =
111 | match action with
112 | Nope -> etat
113 |
114 | let createElement ~initialState ~changerVue ~onUpdate =
115 | fun ~children:_ () ->
116 | component
117 | (fun hooks ->
118 | let ({_} (* nouvel etat *) as etat, _ (* dispatch *), hooks) =
119 | React.Hooks.reducer ~initialState reducer hooks
120 | in let () = onUpdate (`VueParDefaut etat) in
121 | (hooks, View.createElement ~children:[] ()))
122 | end
123 | *)
124 |
125 | module Bouton = struct
126 | let style_btn = Style.[fontSize 25; fontFamily "Roboto-Regular.ttf"]
127 |
128 | let menu_retour ~onMouseUp ?(style=[]) () =
129 | Text.createElement ~text:(I18n.retour ()) ~onMouseUp
130 | ~style:(style @ style_btn)
131 | ~children:[] ()
132 |
133 | let calculer ~onMouseUp ?(style=[]) () =
134 | Text.createElement ~text:(I18n.calculer ()) ~onMouseUp
135 | ~style:(style @ style_btn)
136 | ~children:[] ()
137 |
138 | let effacer ~onMouseUp ?(style=[]) () =
139 | Text.createElement ~text:(I18n.effacer ()) ~onMouseUp
140 | ~style:(style @ style_btn)
141 | ~children:[] ()
142 |
143 | let menu_historique ~onMouseUp ?(style=[]) () =
144 | Text.createElement ~text:(I18n.menu_historique ()) ~onMouseUp
145 | ~style:(style @ style_btn)
146 | ~children:[] ()
147 |
148 | let menu_matrices ~onMouseUp ?(style=[]) () =
149 | Text.createElement ~text:(I18n.menu_matrices ()) ~onMouseUp
150 | ~style:(style @ style_btn)
151 | ~children:[] ()
152 |
153 | let menu_accueil ~onMouseUp ?(style=[]) () =
154 | Text.createElement ~text:(I18n.menu_accueil ()) ~onMouseUp
155 | ~style:(style @ style_btn)
156 | ~children:[] ()
157 |
158 | let menu_calcul ~onMouseUp ?(style=[]) () =
159 | Text.createElement ~text:(I18n.menu_calcul ()) ~onMouseUp
160 | ~style:(style @ style_btn)
161 | ~children:[] ()
162 |
163 | let menu_equations ~onMouseUp ?(style=[]) () =
164 | Text.createElement ~text:(I18n.menu_equations ()) ~onMouseUp
165 | ~style:(style @ style_btn)
166 | ~children:[] ()
167 |
168 | let plus ~onMouseUp ?(style=[]) () =
169 | Text.createElement ~text:"+" ~onMouseUp
170 | ~style:(style @ style_btn)
171 | ~children:[] ()
172 |
173 | let moins ~onMouseUp ?(style=[]) () =
174 | Text.createElement ~text:"-" ~onMouseUp
175 | ~style:(style @ style_btn)
176 | ~children:[] ()
177 | end
178 |
179 | module VueBonus = struct
180 | let createElement ~changerVue ~onUpdate:_ ~children:_ () =
181 | let retour_maison =
182 | Bouton.menu_retour ~onMouseUp:(fun _ -> changerVue `VueAccueil)
183 | ~style:Style.[position `Absolute; bottom 10; right 10] ()
184 | in Minesweeper_lib.MineSweeper.createElement ~children:[retour_maison] ()
185 | end
186 |
187 | module Calcul = struct
188 | let component = React.component "Calcul"
189 |
190 | type action =
191 | Vider
192 | | MiseAJour of string
193 | | Calculer
194 |
195 | let reducer action etat =
196 | match action with
197 | Vider -> {etat with valeur = ""}
198 | | MiseAJour valeur -> {etat with valeur} (* ici on met à jour notre état *)
199 | | Calculer ->
200 | let res = etat.valeur in
201 | let res, cxt =
202 | try
203 | Noyau.Moteur.evaluate_with_history res etat.context
204 | with
205 | Failure msg -> msg, etat.context (* old context *)
206 | | Division_by_zero ->
207 | I18n.division_par_zero (), etat.context (* old context *)
208 | in let res = etat.valeur ^ " = " ^ res in
209 | {
210 | liste_historique = res :: etat.liste_historique;
211 | context = cxt;
212 | valeur = "";
213 | res
214 | }
215 |
216 | let createElement ~initialState ~changerVue ~onUpdate =
217 | let containerStyle =
218 | Style.[
219 | position `Absolute;
220 | justifyContent `Center;
221 | alignItems `Center;
222 | bottom 0;
223 | top 0;
224 | left 0;
225 | right 0;
226 | ]
227 | in let textStyle =
228 | Style.[
229 | fontSize 25;
230 | fontFamily "Roboto-Regular.ttf";
231 | bottom 0;
232 | top 0;
233 | left 0;
234 | right 0;
235 | ]
236 | in fun ~children:_ () ->
237 | component (function hooks ->
238 | let ({valeur; res; _} as etat, dispatch, hooks) =
239 | React.Hooks.reducer ~initialState reducer hooks
240 | in let () = onUpdate (`Calcul etat) in
241 | let bouton_calc =
242 | Bouton.calculer ~style:[] ~onMouseUp:(fun _ -> dispatch Calculer) ()
243 | in let bouton_supp =
244 | Bouton.effacer ~style:Style.[marginHorizontal 20]
245 | ~onMouseUp:(fun _ -> dispatch Vider) ()
246 | in let sous_bout =
247 | View.createElement ~style:Style.[flexDirection `Row]
248 | ~children:[bouton_calc; bouton_supp] ()
249 | in let bouton_his =
250 | Bouton.menu_historique
251 | ~style:Style.[position `Absolute; left 10; bottom 10]
252 | ~onMouseUp:(fun _ -> changerVue `VueHistorique) ()
253 | in let bouton_acc =
254 | Bouton.menu_accueil
255 | ~style:Style.[position `Absolute; bottom 10; right 10]
256 | ~onMouseUp:(fun _ -> changerVue `VueAccueil) ()
257 | in let boutton_mat =
258 | Bouton.menu_matrices
259 | ~onMouseUp:(fun _ -> changerVue `VueMatrice)
260 | ~style:Style.[justifyContent `Center;
261 | position `Absolute; bottom 50; right 10]
262 | ()
263 | in let boutton_equ =
264 | Bouton.menu_equations
265 | ~onMouseUp:(fun _ -> changerVue `VueEquation)
266 | ~style:Style.[justifyContent `Center; position `Absolute;
267 | bottom 90; right 10] ()
268 | in let dimensions = Monitor.getPrimaryMonitor () |> Monitor.getSize in
269 | hooks,
270 | View.createElement ~style:containerStyle ~children:[
271 | Input.createElement
272 | ~style:Style.[color (Color.rgb 25. 5. 5.); bottom 0; top 0;
273 | left 0; right 0; width (
274 | let taille = max 200 (String.length valeur * 10 + 20) in
275 | if taille < dimensions.width / 2 - 20 then
276 | taille
277 | else
278 | dimensions.width / 2 - 20
279 | )]
280 | ~value:valeur ~placeholder:"Entrer votre calcul"
281 | ~onChange:(fun {value; _} -> dispatch(MiseAJour value))
282 | ~children:[] ();
283 | Text.createElement ~text:res(* retour du moteur *) ~style:textStyle
284 | ~children:[] (); sous_bout; bouton_acc; bouton_his;
285 | boutton_equ; boutton_mat] ())
286 | end
287 |
288 | module Historique = struct
289 | let component = React.component "Historique"
290 |
291 | let createElement historique ~changerVue ~onUpdate:_ =
292 | let containerStyle =
293 | Style.[
294 | position `Absolute;
295 | justifyContent `Center;
296 | alignItems `Center;
297 | bottom 0;
298 | top 0;
299 | left 0;
300 | right 0
301 | ]
302 | in let textStyle =
303 | Style.[
304 | fontSize 25;
305 | left 0;
306 | right 0;
307 | bottom 0;
308 | top 0;
309 | fontFamily "Roboto-Regular.ttf"
310 | ]
311 | in let histol hist =
312 | let txt_gen = Text.createElement ~style:textStyle ~children:[] in
313 | List.map (fun text -> txt_gen ~text ()) hist
314 | in fun ~children:_ () ->
315 | component (fun hooks ->
316 | let bouton_retour =
317 | Bouton.menu_retour ~onMouseUp:(fun _ -> changerVue `VueCalcul)
318 | ~style:Style.[position `Absolute; bottom 10; right 10] ()
319 | in hooks,
320 | View.createElement ~style:containerStyle
321 | ~children:(bouton_retour :: (histol historique)) ())
322 | end
323 |
324 | module Matrice = struct
325 | let component = React.component "Matrice"
326 |
327 | type 'a action =
328 | MiseAJour of int * int * int * string(* * ('a -> unit) *)
329 | | MiseAJourEntete of int * string(* * ('a -> unit) *)
330 | | ChangerMode of matrice_mode
331 | | Calculer of matrice_mode
332 |
333 | let reducer action etat =
334 | match action with
335 | MiseAJour (id, i, j, v(*, f*)) ->
336 | let mat =
337 | if id = 1 then
338 | etat.matrice1
339 | else
340 | etat.matrice2
341 | in let () =
342 | try
343 | let _ = float_of_string v in
344 | mat.(i).(j) <- v
345 | with Failure _ -> ()
346 | in (*let () = f (`Matrice etat) in*)
347 | if id = 1 then
348 | {etat with matrice1 = mat}
349 | else
350 | {etat with matrice2 = mat}
351 | | MiseAJourEntete (j, v(*, f*)) ->
352 | let () = etat.matrice1.(0).(j) <- v in
353 | {etat with matrice1 = etat.matrice1}
354 | | ChangerMode m ->
355 | if m <> `Solveur then
356 | {
357 | etat with mode = m;
358 | taille2 = (let (h, _) = etat.taille1 in (h, 2));
359 | taille_res = (let (h, _) = etat.taille_res in (h, 2));
360 | }
361 | else
362 | {
363 | etat with mode = m;
364 | taille2 = (let (h, _) = etat.taille1 in (h, 1));
365 | taille_res = (let (h, _) = etat.taille_res in (h, 1));
366 | }
367 | | Calculer `Solveur ->
368 | etat
369 | | Calculer _ ->
370 | let array_map2 f = Array.map (fun e -> Array.map f e) in
371 | let m1 = array_map2 float_of_string etat.matrice1 in
372 | let m2 = array_map2 float_of_string etat.matrice2 in
373 | let f =
374 | (
375 | match etat.mode with
376 | `Addition -> Modules.Matrix.Test_float_matrix.additioner
377 | | `Soustraction -> Modules.Matrix.Test_float_matrix.soustraire
378 | | `Multiplication -> Modules.Matrix.Test_float_matrix.multiplier
379 | | _ -> Modules.Matrix.Test_float_matrix.additioner
380 | )
381 | in let matrice_res = f m1 m2 in
382 | let matrice_res = array_map2 string_of_float matrice_res in
383 | {
384 | etat with matrice_res;
385 | taille_res = (Array.length matrice_res, Array.length matrice_res.(0));
386 | }
387 |
388 |
389 | let createElement ~initialState ~changerVue ~onUpdate =
390 | fun ~children:_ () ->
391 | component (fun hooks ->
392 | let (etat (* nouvel etat *), dispatch, hooks) =
393 | React.Hooks.reducer ~initialState reducer hooks
394 | in let () = onUpdate (`Matrice etat) in
395 | let dessiner_matrice (h, w) f =
396 | let input = ref [] in
397 | let row_gen = View.createElement ~style:Style.[flexDirection(`Row)] in
398 | let () =
399 | for i = pred h downto 0 do
400 | let row = ref [] in
401 | let () =
402 | for j = pred w downto 0 do
403 | row := (f i j) :: !row
404 | done
405 | in input := (row_gen ~children:!row ()) :: !input
406 | done
407 | in (View.createElement ~children:!input) ()
408 | in let input_gen =
409 | Input.createElement
410 | ~style:Style.[color (Color.rgb 255. 255. 255.); width 100;
411 | margin2 ~horizontal:40 ~vertical:10]
412 | in let m1 =
413 | dessiner_matrice etat.taille1 (fun i j -> input_gen
414 | ~value:etat.matrice1.(i).(j)
415 | ~placeholder:etat.matrice1.(0).(j)
416 | ~onChange:(fun {value; _} ->
417 | if i = 0 && etat.mode = `Solveur then
418 | dispatch(MiseAJourEntete (j, value(*, onUpdate *)))
419 | else
420 | dispatch(MiseAJour (1, i, j, value(*, onUpdate *)))
421 | )
422 | ~children:[] ())
423 | in let op: Dropdown.items =
424 | [
425 | {value = "+"; label = "+ ";
426 | (* all this space are for a bug *)};
427 | {value = "-"; label = "- ";};
428 | {value = "*"; label = "* ";};
429 | (*{value = "resoudre"; label = "resoudre ";};*)
430 | ]
431 | in let dropdown =
432 | Dropdown.createElement ~items:op
433 | ~onItemSelected:(fun {value = a; _} -> dispatch ((function
434 | "+" -> ChangerMode `Addition
435 | | "-" -> ChangerMode `Soustraction
436 | | "*" -> ChangerMode `Multiplication
437 | | "resoudre" -> ChangerMode `Solveur
438 | | _ -> failwith "impossible") a))
439 | ~children:[] ()
440 | in let m2 =
441 | dessiner_matrice etat.taille2 (fun i j -> input_gen
442 | ~value:etat.matrice2.(i).(j)
443 | ~placeholder:etat.matrice2.(0).(j)
444 | ~onChange:(fun {value; _} ->
445 | if i = 0 && etat.mode = `Solveur then
446 | dispatch(MiseAJourEntete (j, value(*, onUpdate *)))
447 | else
448 | dispatch(MiseAJour (2, i, j, value(*, onUpdate *)))
449 | )
450 | ~children:[] ())
451 | in let m_res =
452 | dessiner_matrice etat.taille_res (fun i j -> input_gen
453 | ~value:etat.matrice_res.(i).(j)
454 | ~children:[] ())
455 | in let bouton_calc =
456 | Bouton.calculer
457 | ~onMouseUp:(fun _ -> dispatch (Calculer etat.mode))
458 | ~style:Style.[position `Absolute; bottom 10; right 10] ()
459 | in let bouton_retour =
460 | Bouton.menu_accueil
461 | ~onMouseUp:(fun _ -> changerVue `VueAccueil)
462 | ~style:Style.[position `Absolute; bottom 10; left 10] ()
463 | in let boutton_equ =
464 | Bouton.menu_equations ~onMouseUp:(fun _ -> changerVue `VueEquation)
465 | ~style:Style.[justifyContent `Center; position `Absolute;
466 | bottom 90; left 10] ()
467 | in let boutton_cal =
468 | Bouton.menu_calcul ~onMouseUp:(fun _ -> changerVue `VueCalcul)
469 | ~style:Style.[justifyContent `Center; position `Absolute;
470 | bottom 50; left 10] ()
471 | in let children1 =
472 | [bouton_retour; bouton_calc; boutton_cal; boutton_equ]
473 | in let chmttaille id c d (a, b) =
474 | match id with
475 | 1 when d ->
476 | if c then
477 | etat.taille1 <- (a + 1, b)
478 | else if a > 1 then
479 | etat.taille1 <- (a - 1, b)
480 | | 1 ->
481 | if c then
482 | etat.taille1 <- (a, b + 1)
483 | else if b > 1 then
484 | etat.taille1 <- (a, b - 1)
485 | | 2 when d ->
486 | if c then
487 | etat.taille2 <- (a + 1, b)
488 | else if a > 1 then
489 | etat.taille2 <- (a - 1, b)
490 | | 2 ->
491 | if c then
492 | etat.taille2 <- (a, b + 1)
493 | else if b > 1 then
494 | etat.taille2 <- (a, b - 1)
495 | | 3 when d ->
496 | if c then
497 | etat.taille_res <- (a + 1, b)
498 | else if a > 1 then
499 | etat.taille_res <- (a - 1, b)
500 | | _ ->
501 | if c then
502 | etat.taille_res <- (a, b + 1)
503 | else if b > 1 then
504 | etat.taille_res <- (a, b - 1)
505 | in let chmtmat id (a, b) =
506 | match id with
507 | 1 -> etat.matrice1 <- Array.make_matrix a b "0"
508 | | 2 -> etat.matrice2 <- Array.make_matrix a b "0"
509 | | _ -> etat.matrice_res <- Array.make_matrix a b "0"
510 | (*in let squareu id signe =
511 | match id with
512 | 1 -> chmttaille 1 signe true etat.taille1;
513 | chmttaille 1 signe false etat.taille1; chmtmat 1 etat.taille1
514 | | 2 -> chmttaille 2 signe true etat.taille2;
515 | chmttaille 2 signe false etat.taille2; chmtmat 2 etat.taille2
516 | | _ -> chmttaille 3 signe true etat.taille_res;
517 | chmttaille 3 signe false etat.taille_res;
518 | chmtmat 3 etat.taille_res*)
519 | in let mat1cou =
520 | Bouton.plus
521 | ~onMouseUp:(fun _ -> (*if etat.mode = `Multiplication then
522 | begin*)
523 | chmttaille 1 true true etat.taille1; chmtmat 1 etat.taille1;
524 | (*chmttaille 3 true true etat.taille_res;
525 | chmtmat 3 etat.taille_res;*)
526 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0))) (*
527 | end
528 | else
529 | begin
530 | squareu 1 true; squareu 2 true; squareu 3 true;
531 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0)));
532 | end*) ) ~style:[] ()
533 | in let mat1cod =
534 | Bouton.moins ~style:Style.[marginHorizontal 20]
535 | ~onMouseUp:(fun _ -> (*if etat.mode = `Multiplication then
536 | begin*)
537 | chmttaille 1 false true etat.taille1; chmtmat 1 etat.taille1;
538 | (*chmttaille 3 false true etat.taille_res;
539 | chmtmat 3 etat.taille_res;*)
540 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0))) (*
541 | end
542 | else
543 | begin
544 | squareu 1 false; squareu 2 false; squareu 3 false;
545 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0)))
546 | end*)) ()
547 | in let boutton_mat1c =
548 | View.createElement
549 | ~style:Style.[flexDirection `Row; flexGrow 2;
550 | marginHorizontal 50]
551 | ~children:[mat1cou; mat1cod] ()
552 | in let mat2cou =
553 | Bouton.plus ~style:Style.[marginHorizontal 20]
554 | ~onMouseUp:(fun _ ->
555 | chmttaille 2 true true etat.taille2; chmtmat 2 etat.taille2;
556 | dispatch(MiseAJour (2, 0, 0, etat.matrice2.(0).(0)))) ()
557 | in let mat2cod =
558 | Bouton.moins
559 | ~onMouseUp:(fun _ ->
560 | chmttaille 2 false true etat.taille2; chmtmat 2 etat.taille2;
561 | dispatch(MiseAJour (2, 0, 0, etat.matrice2.(0).(0)))) ()
562 | in let boutton_mat2c =
563 | View.createElement
564 | ~style:Style.[flexDirection `RowReverse; marginHorizontal 50]
565 | ~children:(
566 | (*if etat.mode = `Multiplication then*)
567 | [mat2cou; mat2cod]
568 | (*else
569 | [mat1cou; mat1cod]*)) ()
570 | in let boutton_matc =
571 | View.createElement ~style:Style.[flexDirection`Row]
572 | ~children:[boutton_mat1c; boutton_mat2c] ()
573 | in let mat1liu =
574 | Bouton.plus
575 | ~onMouseUp:(fun _ -> (*if etat.mode = `Multiplication then
576 | begin*)
577 | chmttaille 1 true false etat.taille1; chmtmat 1 etat.taille1;
578 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0)))
579 | (*end
580 | else
581 | begin
582 | squareu 1 true; squareu 2 true; squareu 3 true;
583 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0)))
584 | end*)) ()
585 | in let mat1lid = Bouton.moins
586 | ~onMouseUp:(fun _ ->(*if etat.mode = `Multiplication then
587 | begin*)
588 | chmttaille 1 false false etat.taille1; chmtmat 1 etat.taille1;
589 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0)))
590 | (*end
591 | else
592 | begin
593 | squareu 1 false; squareu 2 false; squareu 3 false;
594 | dispatch(MiseAJour (1, 0, 0, etat.matrice1.(0).(0)))
595 | end*)) ()
596 | in let boutton_mat1l =
597 | View.createElement ~children:[mat1liu; mat1lid] ()
598 | in let mat2liu =
599 | Bouton.plus
600 | ~onMouseUp:(fun _ ->
601 | chmttaille 2 true false etat.taille2; chmtmat 2 etat.taille2;
602 | (*chmttaille 3 true false etat.taille_res;
603 | chmtmat 3 etat.taille_res;*)
604 | dispatch(MiseAJour (2, 0, 0, etat.matrice2.(0).(0)))) ()
605 | in let mat2lid =
606 | Bouton.moins
607 | ~onMouseUp:(fun _ ->
608 | chmttaille 2 false false etat.taille2; chmtmat 2 etat.taille2;
609 | (*chmttaille 3 false false etat.taille_res;
610 | chmtmat 3 etat.taille_res;*)
611 | dispatch(MiseAJour (2, 0, 0, etat.matrice2.(0).(0)))) ()
612 | in let boutton_mat2l =
613 | View.createElement
614 | ~children:(
615 | (*if etat.mode = `Multiplication then*)
616 | [mat2liu; mat2lid]
617 | (*else
618 | [mat1liu; mat1lid]*)) ()
619 | in let children =
620 | View.createElement ~style:Style.[flexDirection `Row]
621 | ~children:[boutton_mat1l; m1; dropdown; m2; boutton_mat2l] ()
622 | in hooks,
623 | View.createElement
624 | ~style:Style.[position `Absolute; alignItems `Center; bottom 0;
625 | top 0; left 0; right 0]
626 | ~children:(boutton_matc :: children :: m_res :: children1) ())
627 | end
628 |
629 | (*
630 | module Equation_old = struct
631 |
632 | let component = React.component "Equation"
633 |
634 | type 'a action =
635 | MiseAJour of int * int * string
636 | | MiseAJourVariable of int * int * string
637 | | Calculer of int
638 |
639 | let reducer action etat =
640 | match action with
641 | MiseAJour (i, j, v) ->
642 | let mat = etat.mat1
643 | in let _ = mat.(i).(j) <- v in
644 | {etat with mat1 = mat}
645 | | MiseAJourVariable (i, j, v) ->
646 | let mat = etat.mat2
647 | in let _ = mat.(i).(j) <- v in
648 | {etat with mat2 = mat}
649 | | Calculer _ ->
650 | let array_map2 f = Array.map (fun e -> Array.map f e) in
651 | let m1 = array_map2 float_of_string etat.mat1 in
652 | let m2 = array_map2 float_of_string etat.mat2 in
653 | let f = (fun _ -> "0" ) in
654 | let res = "" (* f m1 m2 *) in
655 | {etat with res}
656 |
657 |
658 | let createElement ~initialState ~changerVue ~onUpdate =
659 | fun ~children:_ () ->
660 | component (fun hooks ->
661 | let (etat (* nouvel etat *), dispatch, hooks) =
662 | React.Hooks.reducer ~initialState reducer hooks
663 | in let () = onUpdate (`Equation etat) in
664 | let bouton_acc =
665 | Bouton.menu_accueil
666 | ~onMouseUp:(fun _ -> changerVue `VueAccueil)
667 | ~style:Style.[justifyContent `Center; position `Absolute;
668 | bottom 10; left 10] ()
669 | in let bouton_calc =
670 | Bouton.calculer ~onMouseUp:(fun _ -> dispatch (Calculer 1))
671 | ~style:Style.[position `Absolute; bottom 10; right 10] ()
672 | in let egal =
673 | Text.createElement ~text:"=" ~style:Style.[fontSize 25;
674 | fontFamily "Roboto-Regular.ttf"; marginVertical 15] ~children:[] ()
675 | in let boutton_mat =
676 | Bouton.menu_matrices
677 | ~onMouseUp:(fun _ -> changerVue `VueMatrice)
678 | ~style:Style.[justifyContent `Center; position `Absolute;
679 | bottom 90; left 10] ()
680 | in let boutton_cal =
681 | Bouton.menu_calcul ~onMouseUp:(fun _ -> changerVue `VueCalcul)
682 | ~style:Style.[justifyContent `Center; position `Absolute;
683 | bottom 50; left 10] ()
684 | in let rec inc_to_list = function
685 | [] -> []
686 | | e :: l -> (Text.createElement ~text:e ~style:Style.[
687 | fontSize 25; fontFamily "Roboto-Regular.ttf";
688 | marginHorizontal 95]
689 | ~children:[] ()) :: inc_to_list l
690 | in let dessiner_matrice (h, w) f =
691 | let input = ref [] in
692 | let row_gen = View.createElement ~style:Style.[flexDirection `Row] in
693 | let () =
694 | for i = pred h downto 0 do
695 | let row = ref [] in
696 | let () =
697 | for j = pred w downto 0 do
698 | row := (f i j) :: !row
699 | done
700 | in input := (row_gen ~children:!row ()) :: !input
701 | done
702 | in (View.createElement ~children:!input) ()
703 | in let m1 =
704 | dessiner_matrice (etat.lines, etat.nbr_inc) (fun i j ->
705 | Input.createElement
706 | ~style:Style.[color (Color.rgb 255. 255. 255.); width 100;
707 | margin2 ~horizontal:40 ~vertical:10]
708 | ~value:etat.mat1.(i).(j)
709 | ~placeholder:etat.mat1.(i).(j)
710 | ~onChange:(fun {value; _} -> dispatch(MiseAJour (i, j, value)))
711 | ~children:[] ())
712 | in let m2 =
713 | dessiner_matrice (etat.lines, 1) (fun i j -> Input.createElement
714 | ~style:Style.[color (Color.rgb 255. 255. 255.); width 100;
715 | margin2 ~horizontal:40 ~vertical:10]
716 | ~value:etat.mat2.(i).(j)
717 | ~placeholder:etat.mat2.(i).(j)
718 | ~onChange:(fun {value; _} ->
719 | dispatch(MiseAJourVariable (i, j, value)))
720 | ~children:[] ())
721 | in let add_inc () =
722 | let suf = List.nth etat.inconnu (etat.nbr_inc - 1)
723 | in let inc = 1 + int_of_char suf.[0] in
724 | let inc =
725 | let inc = if inc > 122 then inc - 26 else inc in
726 | String.make 1 (char_of_int inc)
727 | in let inc = (
728 | if (List.exists (fun a -> String.equal a inc) etat.inconnu) then
729 | String.make ((String.length (suf)) + 1) inc.[0]
730 | else
731 | inc)
732 | in let _ = etat.inconnu <- etat.inconnu @ [inc] in
733 | etat.nbr_inc <- etat.nbr_inc + 1
734 | in let minus_inc () =
735 | if etat.nbr_inc > 1 then
736 | let (_ :: l) = List.rev etat.inconnu in
737 | let () = etat.inconnu <- List.rev l in
738 | let () = etat.nbr_inc <- etat.nbr_inc - 1 in
739 | etat.mat1 <- Array.make_matrix 1 etat.nbr_inc "0"
740 | in let boutton_addinc =
741 | Bouton.plus ~style:Style.[marginHorizontal 10] ~onMouseUp:(fun _ ->
742 | add_inc ();
743 | etat.mat1 <- Array.make_matrix etat.lines etat.nbr_inc "0";
744 | dispatch(MiseAJour (0, 0, etat.mat1.(0).(0)))) ()
745 | in let boutton_mininc =
746 | Bouton.moins ~style:Style.[marginHorizontal 10]
747 | ~onMouseUp:(fun _ -> minus_inc ();
748 | dispatch(MiseAJour (0, 0, etat.mat1.(0).(0)))) ()
749 | (*in let boutton_addline =
750 | Text.createElement ~text:"+" ~onMouseUp:(fun _ ->
751 | etat.lines <- etat.lines + 1;
752 | etat.mat1 <- Array.make_matrix etat.lines etat.nbr_inc "0";
753 | etat.mat2 <- Array.make_matrix etat.lines 1 "0";
754 | dispatch(MiseAJour (1, 0, 0, "0")))
755 | ~style:Style.[fontSize 25; fontFamily "Roboto-Regular.ttf";
756 | marginHorizontal 10]
757 | ~children:[] ()
758 | in let boutton_minline =
759 | Bouton.moins ~onMouseUp:(fun _ ->
760 | if etat.lines > 1 then
761 | begin
762 | etat.lines <- etat.lines - 1;
763 | etat.mat1 <- Array.make_matrix etat.lines etat.nbr_inc "0";
764 | etat.mat2 <- Array.make_matrix etat.lines 1 "0";
765 | dispatch(MiseAJour (1, 0, 0, "0"))
766 | end )
767 | ~style:Style.[fontSize 25; fontFamily "Roboto-Regular.ttf";
768 | marginHorizontal 10]
769 | ~children:[] ()*)
770 | in let children =
771 | View.createElement ~children:[boutton_addinc; boutton_mininc] ()
772 | in let list_inc =
773 | View.createElement
774 | ~style:Style.[flexDirection `Row; alignSelf `FlexStart]
775 | ~children:(children :: (inc_to_list etat.inconnu)) ()
776 | in let children =
777 | View.createElement
778 | ~style:Style.[flexDirection `Row; alignSelf `FlexStart]
779 | ~children:[m1; egal; m2] ()
780 | (*in let line = View.createElement
781 | ~style:Style.[flexDirection `Row; alignSelf `FlexStart]
782 | ~children:[boutton_addline; boutton_minline] ()*)
783 | in let resultat =
784 | Text.createElement ~text:etat.res
785 | ~style:Style.[fontSize 25; fontFamily "Roboto-Regular.ttf"]
786 | ~children:[] ()
787 | in hooks,
788 | View.createElement
789 | ~style:Style.[position `Absolute; alignItems `Center; bottom 0;
790 | top 0; left 0; right 0]
791 | ~children:[list_inc; children; resultat;
792 | (*line;*) bouton_acc; boutton_cal; boutton_mat; bouton_calc] ())
793 | end
794 | *)
795 | module Equation = struct
796 | type action =
797 | Editer_inconnu of int * string
798 | | Editer_coefficient of int * int * string
799 | | Ajouter_inconnu
800 | | Enlever_inconnu
801 | | Ajouter_ligne
802 | | Enlever_ligne
803 | | Calculer
804 |
805 | let reducer action etat =
806 | match action with
807 | Editer_inconnu (i, v) ->
808 | let inconnues = etat.inconnues in
809 | let () = inconnues.(i) <- v in
810 | {etat with inconnues}
811 | | Editer_coefficient (j, i, v) ->
812 | let coef = etat.coef in
813 | let () = coef.(j).(i) <- v in
814 | {etat with coef}
815 | | Ajouter_inconnu ->
816 | {
817 | etat with
818 | inconnues = Array.append etat.inconnues [| "" |];
819 | coef =
820 | Array.map (fun inc ->
821 | let l = Array.append inc [| "" |] in
822 | let () = l.(etat.nbr_inc + 1) <- l.(etat.nbr_inc) in
823 | let () = l.(etat.nbr_inc) <- "" in
824 | l) etat.coef;
825 | nbr_inc = etat.nbr_inc + 1;
826 | }
827 | | Enlever_inconnu ->
828 | if etat.nbr_inc > 1 then
829 | {
830 | etat with
831 | inconnues = Array.sub etat.inconnues 0 (etat.nbr_inc - 1);
832 | coef =
833 | Array.map (fun inc ->
834 | let l = Array.sub inc 0 etat.nbr_inc in
835 | let () = l.(etat.nbr_inc - 1) <- inc.(etat.nbr_inc) in
836 | l) etat.coef;
837 | nbr_inc = etat.nbr_inc - 1;
838 | }
839 | else
840 | etat
841 | | Ajouter_ligne ->
842 | {
843 | etat with
844 | coef = Array.append etat.coef [| Array.make (etat.nbr_inc + 1) "" |];
845 | nbr_ligne = etat.nbr_ligne + 1;
846 | }
847 | | Enlever_ligne ->
848 | if etat.nbr_ligne > 1 then
849 | {
850 | etat with
851 | coef = Array.sub etat.coef 0 (etat.nbr_ligne - 1);
852 | nbr_ligne = etat.nbr_ligne - 1;
853 | }
854 | else
855 | etat
856 | | Calculer ->
857 | let open Noyau.Moteur.Expr_matrix in
858 | let e =
859 | if Array.for_all ((<>) "") etat.inconnues then
860 | let coef =
861 | Array.map (Array.map (fun e -> if e = "" then "0" else e)) etat.coef
862 | in try
863 | solveur coef etat.nbr_inc etat.nbr_ligne etat.inconnues
864 | with Failure s -> Erreur s
865 | else
866 | Erreur (I18n.champ_variable_vide ())
867 | in {
868 | etat with
869 | resultat = Some e;
870 | }
871 |
872 | let component = React.component "Equation"
873 |
874 | let createElement ~initialState ~changerVue ~onUpdate =
875 | fun ~children:_ () ->
876 | component (fun hooks ->
877 | let (etat (* nouvel etat *), dispatch, hooks) =
878 | React.Hooks.reducer ~initialState reducer hooks
879 | in let () = onUpdate (`Equation etat) in
880 | let children =
881 | Array.mapi (fun i value ->
882 | Input.createElement ~value
883 | ~style:Style.[color (Color.hex "#fff"); width 100;
884 | marginHorizontal 20]
885 | ~onChange:(fun {value; _} -> dispatch(Editer_inconnu(i, value)))
886 | ~children:[] ()) etat.inconnues
887 | in let children = Array.to_list children in
888 | let ajouter_inconnu =
889 | Bouton.plus
890 | ~style:Style.[marginHorizontal 20]
891 | ~onMouseUp:(fun _ -> dispatch Ajouter_inconnu) ()
892 | in let enlever_inconnu =
893 | Bouton.moins
894 | ~style:Style.[marginHorizontal 20]
895 | ~onMouseUp:(fun _ -> dispatch Enlever_inconnu) ()
896 | in let egal =
897 | Text.createElement ~text:"="
898 | ~style:Style.[fontSize 25; fontFamily "Roboto-Regular.ttf";
899 | marginHorizontal 10]
900 | ~children:[] ()
901 | in let dessiner_ligne_coef len j arr =
902 | let res =
903 | Input.createElement ~value:arr.(len) ~placeholder:"Résultat"
904 | ~style:Style.[color (Color.hex "#fff"); width 100;
905 | marginHorizontal 20]
906 | ~onChange:(fun {value; _} ->
907 | dispatch(Editer_coefficient(j, len, value)))
908 | ~children:[] ()
909 | in let ret = ref [egal; res] in
910 | let () =
911 | for i = pred len downto 0 do
912 | let e =
913 | Input.createElement ~value:arr.(i)
914 | ~placeholder:etat.inconnues.(i)
915 | ~style:Style.[color (Color.hex "#fff"); width 100;
916 | marginHorizontal 20]
917 | ~onChange:(fun {value; _} ->
918 | dispatch(Editer_coefficient(j, i, value)))
919 | ~children:[] ()
920 | in ret := e :: !ret
921 | done
922 | in
923 | View.createElement ~style:Style.[flexDirection `Row] ~children:!ret ()
924 | in let coef = Array.mapi (dessiner_ligne_coef etat.nbr_inc) etat.coef in
925 | let coef =
926 | View.createElement ~style:Style.[flexDirection `Column]
927 | ~children:(Array.to_list coef) ()
928 | in let inc =
929 | View.createElement ~style:Style.[flexDirection `Row]
930 | ~children:(children @ [ajouter_inconnu; enlever_inconnu]) ()
931 | in let ajouter_ligne =
932 | Bouton.plus
933 | ~style:Style.[marginHorizontal 20]
934 | ~onMouseUp:(fun _ -> dispatch Ajouter_ligne) ()
935 | in let enlever_ligne =
936 | Bouton.moins
937 | ~style:Style.[marginHorizontal 20]
938 | ~onMouseUp:(fun _ -> dispatch Enlever_ligne) ()
939 | in let modifier_ligne =
940 | View.createElement ~style:Style.[flexDirection `Row]
941 | ~children:[ajouter_ligne; enlever_ligne] ()
942 | in let bouton_acc =
943 | Bouton.menu_accueil
944 | ~onMouseUp:(fun _ -> changerVue `VueAccueil)
945 | ~style:Style.[justifyContent `Center; position `Absolute;
946 | bottom 10; left 10] ()
947 | in let bouton_calc =
948 | Bouton.calculer ~onMouseUp:(fun _ -> dispatch Calculer)
949 | ~style:Style.[position `Absolute; bottom 10; right 10] ()
950 | in let boutton_mat =
951 | Bouton.menu_matrices
952 | ~onMouseUp:(fun _ -> changerVue `VueMatrice)
953 | ~style:Style.[justifyContent `Center; position `Absolute;
954 | bottom 90; left 10] ()
955 | in let boutton_cal =
956 | Bouton.menu_calcul ~onMouseUp:(fun _ -> changerVue `VueCalcul)
957 | ~style:Style.[justifyContent `Center; position `Absolute;
958 | bottom 50; left 10] ()
959 | in let resultat =
960 | let open Noyau.Moteur.Expr_matrix in
961 | match etat.resultat with
962 | None -> None
963 | | Some (Erreur text) ->
964 | let style =
965 | Style.[color (Color.hex "#f00"); fontSize 25;
966 | fontFamily "Roboto-Regular.ttf"]
967 | in Some (Text.createElement ~text ~style ~children:[] ())
968 | | Some (Solution_systeme l) ->
969 | let style = Style.[fontSize 25; fontFamily "Roboto-Regular.ttf"] in
970 | let text_gen (variable, valeur) =
971 | let valeur = Noyau.Moteur.texte_depuis_expr valeur in
972 | let text = variable ^ " = " ^ valeur in
973 | Text.createElement ~text ~style ~children:[] ()
974 | in let children = List.map text_gen l in
975 | Some (View.createElement ~children ())
976 | in let children = [boutton_cal; boutton_mat; bouton_calc] in
977 | let children =
978 | match resultat with
979 | None -> children
980 | | Some e -> e :: children
981 | in let children =
982 | inc :: coef :: modifier_ligne :: bouton_acc :: children
983 | in hooks,
984 | View.createElement
985 | ~style:Style.[position `Absolute; bottom 0;
986 | top 0; left 0; right 0; flexDirection `Column]
987 | ~children ()
988 | )
989 | end
990 |
991 | module Accueil = struct
992 | let component = React.component "Accueil"
993 |
994 | type action =
995 | ChangerLangue of I18n.lang
996 |
997 | let reducer action _ (* etat *) =
998 | match action with
999 | ChangerLangue lang ->
1000 | let () = I18n.definir_lang lang in
1001 | {lang}
1002 |
1003 | let createElement ~initialState ~changerVue ~onUpdate =
1004 | fun ~children:_ () ->
1005 | component (fun hooks ->
1006 | let (etat (* nouvel etat *), dispatch, hooks) =
1007 | React.Hooks.reducer ~initialState reducer hooks
1008 | in let () = onUpdate (`Accueil etat) in
1009 | let containerStyle =
1010 | Style.[
1011 | position `Absolute;
1012 | justifyContent `Center;
1013 | alignItems `Center;
1014 | bottom 0;
1015 | top 0;
1016 | left 0;
1017 | right 0
1018 | ]
1019 | in let translate1, hooks =
1020 | Hooks.animation (Animated.floatValue (-250.))
1021 | {
1022 | toValue = 20.;
1023 | duration = Seconds 2.5;
1024 | delay = Seconds 0.;
1025 | repeat = false;
1026 | easing = Easing.linear;
1027 | direction = `Normal;
1028 | } hooks
1029 | in let translate2, hooks =
1030 | Hooks.animation (Animated.floatValue 150.)
1031 | {
1032 | toValue = -90.;
1033 | duration = Seconds 5.;
1034 | delay = Seconds 2.5;
1035 | repeat = false;
1036 | easing = Easing.linear;
1037 | direction = `Normal
1038 | } hooks
1039 | in let scale, hooks =
1040 | Hooks.animation (Animated.floatValue 0.)
1041 | {
1042 | toValue = 1.;
1043 | duration = Seconds 5.;
1044 | delay = Seconds 2.5;
1045 | repeat = false;
1046 | easing = Easing.linear;
1047 | direction = `Normal
1048 | } hooks
1049 | in let imageStyle1 =
1050 | Style.[
1051 | bottom 0;
1052 | top 0;
1053 | left 0;
1054 | right 0;
1055 | width 200;
1056 | height 200;
1057 | transform [Transform.TranslateX translate1]
1058 | ]
1059 | in let imageStyle2 =
1060 | Style.[
1061 | top 0;
1062 | bottom 0;
1063 | right 0;
1064 | left 0;
1065 | width 75;
1066 | height 75;
1067 | transform [
1068 | Transform.TranslateY translate2;
1069 | Transform.ScaleX scale;
1070 | Transform.ScaleY scale;
1071 | ];
1072 | ]
1073 | in let bouton_cal =
1074 | Bouton.menu_calcul ~onMouseUp:(fun _ -> changerVue `VueCalcul)
1075 | ~style:Style.[justifyContent `Center; color (Color.rgb 255. 120. 10.);
1076 | position `Absolute; bottom 10; left 10] ()
1077 | in let bouton_mat =
1078 | Bouton.menu_matrices ~onMouseUp:(fun _ -> changerVue `VueMatrice)
1079 | ~style:Style.[justifyContent `Center; color (Color.rgb 255. 120. 10.);
1080 | position `Absolute; right 10; bottom 10] ()
1081 | in let bouton_equa =
1082 | Bouton.menu_equations ~onMouseUp:(fun _ -> changerVue `VueEquation)
1083 | ~style:Style.[
1084 | justifyContent `Center; color (Color.rgb 255. 120. 10.);
1085 | position `Absolute; bottom 50; right 10] ()
1086 | in let bouton_langue =
1087 | let src = "drapeau_" ^ (I18n.obtenir_lang ()) ^ ".png"
1088 | and style =
1089 | Style.[position `Absolute; top 10; right 10; height 25; width 38]
1090 | and onMouseUp _ =
1091 | let nouvelle_langue =
1092 | match I18n.obtenir_lang () with
1093 | "fr" -> I18n.Anglais
1094 | | "eng" -> I18n.Francais
1095 | | _ -> failwith "langue non reconnu"
1096 | in dispatch (ChangerLangue nouvelle_langue)
1097 | in Image.createElement ~src ~style ~onMouseUp ~children:[] ()
1098 | in hooks,
1099 | View.createElement ~style:containerStyle
1100 | ~children:[bouton_langue;
1101 | Image.createElement
1102 | ~onMouseUp:(fun _ -> changerVue `VueBonus) ~src:"pi.png"
1103 | ~style:imageStyle2 ~children:[] ();
1104 | Image.createElement ~src:"camel.png" ~style:imageStyle1
1105 | ~children:[] ();
1106 | bouton_cal; bouton_equa; bouton_mat;
1107 | ] ())
1108 | end
1109 |
1110 | module Application = struct
1111 | let component = React.component "Application"
1112 |
1113 | type action =
1114 | ChangerVue of vue
1115 |
1116 | let sauvegarde =
1117 | ref {
1118 | equation =
1119 | {
1120 | (*
1121 | inconnu = ["x"];
1122 | nbr_inc = 1;
1123 | lines = 1;
1124 | mat1 = Array.make_matrix 1 1 "0";
1125 | mat2 = Array.make_matrix 1 1 "0";
1126 | res = "";
1127 | *)
1128 | inconnues = Array.make 1 "";
1129 | nbr_inc = 1;
1130 | coef = Array.make_matrix 1 2 "";
1131 | nbr_ligne = 1;
1132 | resultat = None;
1133 | };
1134 | calcul = {
1135 | valeur = "";
1136 | res = " "(* trick to be displayed *);
1137 | liste_historique = !Commune.liste_historique;
1138 | (* TODO: avoid this double list *)
1139 | context = Commune.init_context
1140 | };
1141 | historique = {
1142 | liste = [];
1143 | };
1144 | matrice = {
1145 | mode = `Addition;
1146 | matrice1 = Array.make_matrix 2 2 "0";
1147 | matrice2 = Array.make_matrix 2 2 "0";
1148 | matrice_res = Array.make_matrix 2 2 "0";
1149 | taille1 = (2, 2);
1150 | taille2 = (2, 2);
1151 | taille_res = (2, 2);
1152 | message = "";
1153 | };
1154 | accueil = {
1155 | lang = I18n.Francais;
1156 | };
1157 | }
1158 |
1159 | let reducer action _ (* etat *) =
1160 | match action with
1161 | ChangerVue v -> {(* etat with *) vue_courante = v}
1162 |
1163 | let miseAJour = function
1164 | `Calcul e ->
1165 | let () = sauvegarde := {!sauvegarde with calcul = e} in
1166 | !sauvegarde.historique.liste <- e.liste_historique
1167 | | `Matrice e -> sauvegarde := {!sauvegarde with matrice = e}
1168 | | `Accueil e -> sauvegarde := {!sauvegarde with accueil = e}
1169 | | `Equation e -> sauvegarde := {!sauvegarde with equation = e}
1170 |
1171 | let createElement =
1172 | fun ~children:_ () ->
1173 | component(fun hooks ->
1174 | let {vue_courante}, dispatch, hooks =
1175 | React.Hooks.reducer ~initialState:{vue_courante = `VueAccueil}
1176 | reducer hooks
1177 | in let choisir_vue = function
1178 | `VueCalcul -> Calcul.createElement
1179 | ~initialState:(!sauvegarde.calcul)
1180 | | `VueHistorique -> Historique.createElement
1181 | !sauvegarde.calcul.liste_historique
1182 | | `VueMatrice -> Matrice.createElement
1183 | ~initialState:(!sauvegarde.matrice)
1184 | | `VueAccueil -> Accueil.createElement
1185 | ~initialState:(!sauvegarde.accueil)
1186 | | `VueEquation -> Equation.createElement
1187 | ~initialState:(!sauvegarde.equation)
1188 | | `VueBonus -> VueBonus.createElement
1189 | in hooks,
1190 | (choisir_vue vue_courante)
1191 | ~changerVue:(fun v -> dispatch (ChangerVue v))
1192 | ~onUpdate:miseAJour
1193 | ~children:[] ())
1194 | end
1195 |
1196 | (*
1197 | let init app =
1198 | let win = App.createWindow app "OCalc" in
1199 | Input.createElement ~style:Style.[top (100); left (300); position `Absolute]
1200 | ~children:[] () |>
1201 | UI.start win |> ignore
1202 |
1203 | let init app =
1204 | let win = App.createWindow app "OCalc" in
1205 | Input.createElement ~style:Style.[] ~children:[] () |>
1206 | UI.start win |> ignore
1207 |
1208 | let init app =
1209 | let win = App.createWindow app "OCalc" in
1210 | let op: Dropdown.items = [
1211 | {value = "+"; label = "+";};
1212 | {value = "-"; label = "-";};
1213 | {value = "*"; label = "*";};
1214 | ] in Dropdown.createElement ~items:op ~onItemSelected:(fun _ -> ())
1215 | ~children:[] () |>
1216 | UI.start win |> ignore
1217 | *)
1218 |
1219 | let init app =
1220 | let maximized = Environment.webGL in
1221 | let dimensions = Monitor.getPrimaryMonitor () |> Monitor.getSize in
1222 | let windowWidth = dimensions.width / 2 in
1223 | let windowHeight = dimensions.height / 2 in
1224 | let options_fen =
1225 | WindowCreateOptions.create ~width:windowWidth ~height:windowHeight
1226 | ~maximized ~icon:(Some "logo.png") ~backgroundColor:bgColor ()
1227 | in let fen = App.createWindow ~createOptions:options_fen app "OCalc" in
1228 | let () =
1229 | if not Environment.webGL then
1230 | let xPosition = (dimensions.width - windowWidth) / 2 in
1231 | let yPosition = (dimensions.height - windowHeight) / 2 in
1232 | Window.setPos fen xPosition yPosition
1233 | in let afficher () = Application.createElement ~children:[] () in
1234 | UI.start fen (afficher ()) (afficher ())
1235 |
1236 | let _ = App.start init
1237 |
--------------------------------------------------------------------------------
/src/interfaces/topGui.mli:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topGui.mli
--------------------------------------------------------------------------------
/src/interfaces/topServeur.ml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topServeur.ml
--------------------------------------------------------------------------------
/src/interfaces/topServeur.mli:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topServeur.mli
--------------------------------------------------------------------------------
/src/interfaces/topTest.ml:
--------------------------------------------------------------------------------
1 | open Noyau
2 | open Modules
3 | open Type
4 | open Utils
5 | open Lexer
6 | open Parser
7 | open GrandEntier_on
8 |
9 | let mechant = false
10 |
11 | (*numéro de *)
12 | let (test_total, test_valide_total, suite, test, test_valide) = ref 0, ref 0, ref 0, ref 0, ref 0
13 |
14 | let test_unitaire_assert a b =
15 | let () =
16 | if a <> b then
17 | Printf.printf "Le test #%d n'as pas produit la valeure attendue\n" !test
18 | else
19 | let () = test_valide := !test_valide + 1 in
20 | test_valide_total := !test_valide_total + 1
21 | in let () = test_total := !test_total + 1 in
22 | test := !test + 1
23 |
24 | let init_suite name =
25 | let () = Printf.printf "\n\n\x1b[4mSuite #%d\x1b[0m: %s\n" !suite name in
26 | suite := !suite + 1
27 |
28 | let fin_suite () =
29 | let () =
30 | Printf.printf "%3.2f %% de tests passés pour cette suite\n" (100. *. float_of_int !test_valide /. float_of_int !test) in
31 | let () = test_valide := 0 in
32 | test := 0
33 |
34 | let reinit_test_suite () =
35 | let () = test_total := 0 in
36 | let () = test_valide_total := 0 in
37 | let () = suite := 0 in
38 | let () = test := 0 in
39 | test_valide := 0
40 |
41 |
42 | let () = init_suite "est_entier"
43 |
44 | let () = test_unitaire_assert (est_entier "123" 10) true
45 | let () = test_unitaire_assert (est_entier "-123" 10) true
46 | let () = test_unitaire_assert (est_entier "+123" 10) true
47 | let () = test_unitaire_assert (est_entier "007" 10) true
48 | let () = test_unitaire_assert (est_entier "0" 10) true
49 | let () = test_unitaire_assert (est_entier "" 10) false
50 | let () = test_unitaire_assert (est_entier "123a" 10) false
51 | let () = test_unitaire_assert (est_entier "_123" 10) false
52 | let () = test_unitaire_assert (est_entier "1u23" 10) false
53 |
54 | let () = fin_suite ()
55 |
56 | let () = init_suite "est_entier_base"
57 |
58 | let () = test_unitaire_assert (est_entier_base "12310") false
59 | let () = test_unitaire_assert (est_entier_base "123_10") true
60 | let () = test_unitaire_assert (est_entier_base "(123)_10") true
61 | let () = test_unitaire_assert (est_entier_base "123)_10") false
62 | let () = test_unitaire_assert (est_entier_base "(123_10") false
63 | let () = test_unitaire_assert (est_entier_base "_123_10") false
64 | let () = test_unitaire_assert (est_entier_base "g123_10") false
65 | let () = test_unitaire_assert (est_entier_base "123u_10") false
66 | let () = test_unitaire_assert (est_entier_base "12b3_10") false
67 | let () = test_unitaire_assert (est_entier_base "à12b3_10") false
68 |
69 | let () = fin_suite ()
70 |
71 | let () = init_suite "est_variable"
72 |
73 | let () = test_unitaire_assert (est_variable "a") true
74 | let () = test_unitaire_assert (est_variable "x") true
75 | let () = test_unitaire_assert (est_variable "x'") true
76 | let () = test_unitaire_assert (est_variable "pi") true
77 | let () = test_unitaire_assert (est_variable "pi2") true
78 | let () = test_unitaire_assert (est_variable "pi-2") false
79 | let () = test_unitaire_assert (est_variable "pi_t") true
80 | let () = test_unitaire_assert (est_variable "pi_2") true (*Va être confondu avec est_entier_base ?*)
81 | let () = test_unitaire_assert (est_variable "a_") false (*Termine par un _ *)
82 | let () = test_unitaire_assert (est_variable "Ax") false (*Constante qui commence par une maj ? Matrice ?*)
83 | let () = test_unitaire_assert (est_variable "x'''''") true (*apostrophe ok*)
84 | let () = test_unitaire_assert (est_variable "x'''''123") true
85 | let () = test_unitaire_assert (est_variable "xZE") true (*Majuscule pas à la première ok*)
86 |
87 | let () = fin_suite ()
88 |
89 | let () = init_suite "contient_texte"
90 |
91 | let () = test_unitaire_assert (contient_texte "123" ['+']) false
92 | let () = test_unitaire_assert (contient_texte "123+456" ['+']) true
93 | let () = test_unitaire_assert (contient_texte "123+456" ['-']) false
94 | let () = test_unitaire_assert (contient_texte "123-456+789" ['-'; '+']) true
95 |
96 | let () = fin_suite ()
97 |
98 | let () = init_suite "couper_texte"
99 |
100 | let () = test_unitaire_assert (couper_texte "123" ['+']) ["123"]
101 | let () = test_unitaire_assert (couper_texte "123+456" ['+']) ["123"; "+"; "456"]
102 | let () = test_unitaire_assert (couper_texte "123+456" ['-']) ["123+456"]
103 | let () = test_unitaire_assert (couper_texte "123-456+789" ['-'; '+']) ["123"; "-"; "456"; "+"; "789"]
104 |
105 | let () = fin_suite ()
106 |
107 | let () = init_suite "texte_de_expr"
108 |
109 | let () = test_unitaire_assert (texte_de_expr (Variable "x")) "x"
110 | let () = test_unitaire_assert (texte_de_expr (Operation ("+", [Variable "x"]))) "x"
111 | let () = test_unitaire_assert (texte_de_expr (Operation ("+", [Variable "x"; Variable "y"]))) "(x+y)"
112 | let () = test_unitaire_assert (texte_de_expr (Operation ("*", [Operation ("+", [Variable "x"; Variable "y"])]))) "(x+y)"
113 | let () = test_unitaire_assert (texte_de_expr (Operation ("*", [Variable "z"; Operation ("+", [Variable "x"; Variable "y"])]))) "(z*(x+y))"
114 |
115 | let () = fin_suite ()
116 |
117 | let () = init_suite "expr_de_texte_etend"
118 |
119 | let parse = []
120 | (* this is an old time
121 | let () = test_unitaire_assert (expr_de_texte_etend parse "3445") (Textenonvalide "3445") in
122 | let () = test_unitaire_assert (expr_de_texte_etend parse "x") (Textenonvalide "x") in
123 | *)
124 | let parse =
125 | let parse = (est_multiplication_division, variable_de_multiplication_division) :: parse in
126 | let parse = (est_addition_soustraction, variable_de_addition_soustraction) :: parse in
127 | let parse = (est_variable, variable_de_texte) :: parse in
128 | let parse = (est_entier10, variable_de_entier) :: parse in
129 | parse
130 | let () = test_unitaire_assert (expr_de_texte_etend parse "3445") (Entier (ge "3445"))
131 | let () = test_unitaire_assert (expr_de_texte_etend parse "+3445") (Entier (ge "3445"))
132 | let () = test_unitaire_assert (expr_de_texte_etend parse "-3445") (Entier (ge "-3445"))
133 | let () = test_unitaire_assert (expr_de_texte_etend parse "x+3445") (Operation ("+", [Variable "x"; Entier (ge "3445")]))
134 | let () = test_unitaire_assert (expr_de_texte_etend parse "x+3445-y") (Operation ("+", [Variable "x"; Entier (ge "3445"); Neg (Variable "y")]))
135 | let () = test_unitaire_assert (expr_de_texte_etend parse "-123+x-y") (Operation ("+", [Entier (ge "-123"); Variable "x"; Neg (Variable "y")]))
136 | let () = test_unitaire_assert (expr_de_texte_etend parse "-z") (Neg (Variable "z"))
137 | let () = test_unitaire_assert (expr_de_texte_etend parse "+alexandre") (Variable "alexandre")
138 | let () = test_unitaire_assert (expr_de_texte_etend parse "x") (Variable ("x"))
139 | let () = test_unitaire_assert (expr_de_texte_etend parse "1+2*3") (Operation ("+", [Entier (ge "1"); Operation ("*", [Entier (ge "2"); Entier (ge "3")])]))
140 |
141 | let () = fin_suite ()
142 |
143 | (** test sur les Grand Entiers *)
144 | let grandentier_depuis_texte a = Obj.magic grandentier_depuis_texte a
145 | let texte_depuis_grandentier a = Obj.magic texte_depuis_grandentier a
146 | let a = grandentier_depuis_texte "-5"
147 | let b = grandentier_depuis_texte "-50"
148 | let c = grandentier_depuis_texte "5"
149 | let d = grandentier_depuis_texte "0"
150 | let e = grandentier_depuis_texte "-0"
151 | let _ = grandentier_depuis_texte "-45"
152 |
153 | let () = init_suite "est_negatif"
154 |
155 | let () = test_unitaire_assert (est_negatif a) true
156 | let () = test_unitaire_assert (est_negatif b) true
157 | let () = test_unitaire_assert (est_negatif c) false
158 | let () = test_unitaire_assert (est_negatif d) false
159 | let () = test_unitaire_assert (est_negatif e) false
160 |
161 | let () = fin_suite ()
162 |
163 | let () = init_suite "comparer"
164 |
165 | let () = test_unitaire_assert (comparer a b) ~-1
166 | let () = test_unitaire_assert (comparer b a) 1
167 | let () = test_unitaire_assert (comparer c a) ~-1
168 | let () = test_unitaire_assert (comparer a c) 1
169 | let () = test_unitaire_assert (comparer a d) 1
170 | let () = test_unitaire_assert (comparer d e) 0
171 |
172 | let () = fin_suite ()
173 |
174 | let () = init_suite "additioner"
175 |
176 | let () = test_unitaire_assert (additioner a b) (grandentier_depuis_texte "-55")
177 | let () = test_unitaire_assert (additioner b a) (grandentier_depuis_texte "-55")
178 | let () = test_unitaire_assert (additioner c a) d
179 | let () = test_unitaire_assert (additioner a c) d
180 | let () = if mechant then
181 | test_unitaire_assert (additioner a d) a
182 | let () = test_unitaire_assert (additioner d e) d
183 |
184 | let () = fin_suite ()
185 |
186 | let () = init_suite "soustraire"
187 |
188 | let () = if mechant then
189 | test_unitaire_assert (soustraire a b) (grandentier_depuis_texte "45")
190 | let () = if mechant then
191 | test_unitaire_assert (soustraire b a) (grandentier_depuis_texte "-45")
192 | let () = test_unitaire_assert (soustraire c a) (grandentier_depuis_texte "10")
193 | let () = test_unitaire_assert (soustraire a c) (grandentier_depuis_texte "-10")
194 | let () = test_unitaire_assert (soustraire a d) a
195 | let () = test_unitaire_assert (soustraire d e) d
196 | let () = test_unitaire_assert (soustraire a a) d
197 |
198 | let () = fin_suite ()
199 |
200 | let () = init_suite "multiplier"
201 |
202 | let () = test_unitaire_assert (multiplier a b) (grandentier_depuis_texte "250")
203 | let () = test_unitaire_assert (multiplier b a) (grandentier_depuis_texte "250")
204 | let () = test_unitaire_assert (multiplier c a) (grandentier_depuis_texte "-25")
205 | let () = test_unitaire_assert (multiplier a c) (grandentier_depuis_texte "-25")
206 | let () = test_unitaire_assert (multiplier a d) d
207 | let () = test_unitaire_assert (multiplier d e) d
208 | let () = test_unitaire_assert (multiplier a a) (grandentier_depuis_texte "25")
209 |
210 | let () = fin_suite ()
211 |
212 | let () = init_suite "grandentier_depuis_texte"
213 |
214 | let () = test_unitaire_assert (grandentier_depuis_texte "3445") (false, [5; 4; 4; 3])
215 | let () = test_unitaire_assert (grandentier_depuis_texte "-3445") (true, [5; 4; 4; 3])
216 | let () = test_unitaire_assert (grandentier_depuis_texte "0") (false, [])
217 | let () = test_unitaire_assert (grandentier_depuis_texte "-0") (false, [])
218 |
219 | let () = fin_suite ()
220 |
221 | let () = init_suite "texte_depuis_grandentier"
222 |
223 | let () = test_unitaire_assert (texte_depuis_grandentier (false, [5; 4; 4; 3])) "3445"
224 | let () = test_unitaire_assert (texte_depuis_grandentier (true, [5; 4; 4; 3])) "-3445"
225 | let () = test_unitaire_assert (texte_depuis_grandentier (false, [])) "0"
226 | let () = test_unitaire_assert (texte_depuis_grandentier (true, [])) "0"
227 |
228 | let () = fin_suite ()
229 |
230 | let () = Printf.printf "\n\n%3.2f %% des tests global passés\n" (100. *. float_of_int !test_valide_total /. float_of_int !test_total)
231 | let () = reinit_test_suite ()
232 |
--------------------------------------------------------------------------------
/src/interfaces/topTest.mli:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Et7f3/ocalc/667da625676829307fc59542906ed2075fe818bd/src/interfaces/topTest.mli
--------------------------------------------------------------------------------
/src/modules/I18n.ml:
--------------------------------------------------------------------------------
1 | type lang =
2 | Francais
3 | | Anglais
4 |
5 | let lang = ref Francais
6 |
7 | let definir_lang l =
8 | lang := l
9 |
10 | let obtenir_lang () =
11 | match !lang with
12 | Francais -> "fr"
13 | | Anglais -> "eng"
14 |
15 | let division_par_zero () =
16 | match !lang with
17 | Francais -> "Division par zéro à eu lieu"
18 | | Anglais -> "Division by zero occur"
19 |
20 | let separateur_unite () =
21 | match !lang with
22 | Francais -> ","
23 | | Anglais -> "."
24 |
25 | let impossible_convertir_pas_affectable () =
26 | match !lang with
27 | Francais -> "Impossible de convertir Pas_affectable"
28 | | Anglais -> "We can't convert Pas_affectable"
29 |
30 | let impossible_convertir_vide () =
31 | match !lang with
32 | Francais -> "Impossible de convertir Vide"
33 | | Anglais -> "We can't convert Vide"
34 |
35 | let matrice_mauvaise_dimension () =
36 | match !lang with
37 | Francais -> "matrice de mauvaise dimension"
38 | | Anglais -> "Matrix don't have right size"
39 |
40 | let fichier_inexistant fichier =
41 | match !lang with
42 | Francais -> fichier ^ " n'existe pas"
43 | | Anglais -> fichier ^ " doesn't exist"
44 |
45 | let fichier_pas_math fichier =
46 | match !lang with
47 | Francais -> fichier ^ " n'as pas l'extension .math"
48 | | Anglais -> fichier ^ " isn't a .math file"
49 |
50 | let bienvenue () =
51 | match !lang with
52 | Francais -> "Bienvenue chez OCalc"
53 | | Anglais -> "Walcome at OCalc"
54 |
55 | let sortir_msg () =
56 | match !lang with
57 | Francais -> "tapez sortir ou quitter pour quitter"
58 | | Anglais -> "type exit or quit to quit"
59 |
60 | let sortir_1 () =
61 | match !lang with
62 | Francais -> "sortir"
63 | | Anglais -> "exit"
64 |
65 | let sortir_2 () =
66 | match !lang with
67 | Francais -> "quitter"
68 | | Anglais -> "quit"
69 |
70 | let mauvais_parenthesage () =
71 | match !lang with
72 | Francais -> "Vérifiez vos parenthèses !!!"
73 | | Anglais -> "Some parenthesis mismatch !!!"
74 |
75 | let erreur_de_syntaxe () =
76 | match !lang with
77 | Francais -> "Erreur de syntaxe"
78 | | Anglais -> "Syntax error"
79 |
80 | let definition_valide () =
81 | match !lang with
82 | Francais -> "Définition valide"
83 | | Anglais -> "Definition valid"
84 |
85 | let retour () =
86 | match !lang with
87 | Francais -> "Retour"
88 | | Anglais -> "Back"
89 |
90 | let calculer () =
91 | match !lang with
92 | Francais -> "Calculer"
93 | | Anglais -> "Compute"
94 |
95 | let effacer () =
96 | match !lang with
97 | Francais -> "Effacer"
98 | | Anglais -> "Erase"
99 |
100 | let menu_historique () =
101 | match !lang with
102 | Francais -> "Historique"
103 | | Anglais -> "History"
104 |
105 | let menu_accueil () =
106 | match !lang with
107 | Francais -> "Accueil"
108 | | Anglais -> "Home"
109 |
110 | let menu_calcul () =
111 | match !lang with
112 | Francais -> "Calcul"
113 | | Anglais -> "Calculus"
114 |
115 | let menu_matrices () =
116 | match !lang with
117 | Francais -> "Matrices"
118 | | Anglais -> "Matrix"
119 |
120 | let menu_equations () =
121 | match !lang with
122 | Francais -> "Équations"
123 | | Anglais -> "Solver"
124 |
125 | let contractition_presente () =
126 | match !lang with
127 | Francais -> "Il y a une contradiction présente"
128 | | Anglais -> "Solution doesn't exist"
129 |
130 | let definition_non_autorise () =
131 | match !lang with
132 | Francais -> "Vous ne pouvez pas définir de variable ici"
133 | | Anglais -> "You can't define value here"
134 |
135 | let champ_variable_vide () =
136 | match !lang with
137 | Francais -> "Vous devez donner un nom a toutes les inconnues"
138 | | Anglais -> "You must give a name for all unknown"
139 |
--------------------------------------------------------------------------------
/src/modules/I18n.mli:
--------------------------------------------------------------------------------
1 | type lang =
2 | Francais
3 | | Anglais
4 |
5 | val definir_lang : lang -> unit
6 |
7 | val obtenir_lang : unit -> string
8 |
9 | val division_par_zero : unit -> string
10 |
11 | val separateur_unite : unit -> string
12 |
13 | val impossible_convertir_pas_affectable : unit -> string
14 |
15 | val impossible_convertir_vide : unit -> string
16 |
17 | val matrice_mauvaise_dimension : unit -> string
18 |
19 | val fichier_inexistant : string -> string
20 |
21 | val fichier_pas_math : string -> string
22 |
23 | val bienvenue : unit -> string
24 |
25 | val sortir_msg : unit -> string
26 |
27 | val sortir_1 : unit -> string
28 |
29 | val sortir_2 : unit -> string
30 |
31 | val mauvais_parenthesage : unit -> string
32 |
33 | val erreur_de_syntaxe : unit -> string
34 |
35 | val definition_valide : unit -> string
36 |
37 | val retour : unit -> string
38 |
39 | val calculer : unit -> string
40 |
41 | val effacer : unit -> string
42 |
43 | val menu_historique : unit -> string
44 |
45 | val menu_accueil : unit -> string
46 |
47 | val menu_calcul : unit -> string
48 |
49 | val menu_matrices : unit -> string
50 |
51 | val menu_equations : unit -> string
52 |
53 | val contractition_presente : unit -> string
54 |
55 | val definition_non_autorise : unit -> string
56 |
57 | val champ_variable_vide : unit -> string
58 |
--------------------------------------------------------------------------------
/src/modules/dune:
--------------------------------------------------------------------------------
1 | (library
2 | (name Modules)
3 | (wrapped true)
4 | (modules GrandNum_on GrandEntier_on GrandReel_on GrandRationnel_on Matrix)
5 | (libraries I18n))
6 |
7 | (library
8 | (name I18n)
9 | (wrapped true)
10 | (modules I18n))
11 |
--------------------------------------------------------------------------------
/src/modules/grandEntier_off.ml:
--------------------------------------------------------------------------------
1 | type grandentier = int
2 | (** grandentier est un tuple [(signe négatif, \[unité, dizaine, centaine, ...\])]
3 | [-123] correspond à [(true, \[3; 2; 1\])] *)
4 |
5 | let zero = 0
6 |
7 | let unit = 1
8 |
9 | let est_negatif x = x < 0
10 | (** renvoie [grandentier < 0] *)
11 |
12 | let neg = (~-)
13 | (** renvoie l'oposé *)
14 |
15 | let comparer ga gb =
16 | if ga < gb then
17 | 1
18 | else if ga = gb then
19 | 0
20 | else
21 | -1
22 | (** 1 si ga < gb sinon 0 si ga = gb sinon -1 *)
23 |
24 | let additioner ga gb = ga + gb
25 | (** renvoie ga + gb *)
26 |
27 | let soustraire ga gb = ga - gb
28 | (** renvoie ga - gb *)
29 |
30 | let multiplier ga gb = ga * gb
31 | (** renvoie ga * gb *)
32 |
33 | let rec pgcd ga gb =
34 | if ga = 0 then
35 | gb
36 | else
37 | pgcd (gb mod ga) ga
38 | (** renvoie pgcd(ga, gb) *)
39 |
40 | let diviser_multiple ga gb = ga / gb
41 | (** renvoie ga / gb où ga est multiple de gb *)
42 |
43 | let diviser ga gb =
44 | let pgcd = pgcd ga gb in
45 | ga / pgcd, gb / pgcd
46 | (** renvoie (nominateur, dénominateur) de la fraction ga / gb *)
47 |
48 | let grandentier_depuis_texte sa = int_of_string sa
49 | (** renvoie le grandentier à partir de sa représentation textuelle *)
50 |
51 | let texte_depuis_grandentier ga = string_of_int ga
52 | (** renvoie la représentation textuelle d'un grandentier *)
53 |
--------------------------------------------------------------------------------
/src/modules/grandEntier_off.mli:
--------------------------------------------------------------------------------
1 | type grandentier
2 | val zero : grandentier
3 | val unit : grandentier
4 | val est_negatif : grandentier -> bool
5 | val neg : grandentier -> grandentier
6 | val comparer : grandentier -> grandentier -> int
7 | val additioner : grandentier -> grandentier -> grandentier
8 | val soustraire : grandentier -> grandentier -> grandentier
9 | val multiplier : grandentier -> grandentier -> grandentier
10 | val pgcd : grandentier -> grandentier -> grandentier
11 | val diviser_multiple : grandentier -> grandentier -> grandentier
12 | val diviser : grandentier -> grandentier -> grandentier * grandentier
13 | val grandentier_depuis_texte : string -> grandentier
14 | val texte_depuis_grandentier : grandentier -> string
15 |
--------------------------------------------------------------------------------
/src/modules/grandEntier_on.ml:
--------------------------------------------------------------------------------
1 | type grandentier = bool * int list
2 | (** grandentier est un tuple [(signe négatif, \[unité, dizaine, centaine, ...\])]
3 | [ - 123] correspond à [(true, \[3; 2; 1\])] *)
4 |
5 | (** https://www.youtube.com/watch?v=ih9zBLDr_ro Ca détend **)
6 |
7 | let zero = false, []
8 |
9 | let unit = false, [1]
10 |
11 | (** renvoie [grandentier < 0] *)
12 | let est_negatif (signe, _) = signe
13 |
14 | (** ah **)
15 |
16 | (** renvoie l'oposé *)
17 | let neg (a, b) =
18 | match b with
19 | [] -> false, []
20 | | _ -> not a, b
21 |
22 | let nettoyer_zero a =
23 | let rec n0 = function
24 | [] -> []
25 | | 0 :: c -> n0 c
26 | | c -> List.rev c
27 | in n0 (List.rev a)
28 |
29 | (** 1 si ga < gb sinon 0 si ga = gb sinon -1 *)
30 | (* 1 : gb > ga
31 | 0 : ga = gb
32 | -1 : ga > gb*)
33 |
34 | let comparer_nbr_abs ga gb =
35 | let la = List.length ga
36 | and lb = List.length gb in
37 | if la > lb then
38 | -1
39 | else if la < lb then
40 | 1
41 | else
42 | let rec cna = function
43 | e1 :: ga, e2 :: gb ->
44 | if e1 > e2 then
45 | -1
46 | else if e2 > e1 then
47 | 1
48 | else
49 | cna (ga, gb)
50 | (* this will not happen *)
51 | | [], [] -> 0
52 | | _, [] -> -1
53 | | [], _ -> 1
54 | in cna (List.rev ga, List.rev gb)
55 |
56 | let comparer ga gb =
57 | match ga, gb with
58 | (true, _), (false, _) -> 1
59 | | (false, _), (true, _) -> -1
60 | | (false, b), (false, d) | (true, d), (true, b) -> comparer_nbr_abs b d
61 | (** 1 si ga < gb sinon 0 si ga = gb sinon -1 *)
62 | (* 1 : gb > ga
63 | 0 : ga = gb
64 | -1 : ga > gb*)
65 |
66 | (** Merci la prog :D**)
67 | let bigint_sum big1 big2 =
68 | let rec add = function
69 | [], r | r, [] -> r
70 | | d1 :: r1, d2 :: r2 ->
71 | let s = d1 + d2 in
72 | if s < 10 then
73 | s :: add(r1, r2)
74 | else
75 | (s - 10) :: add (add([1], r1), r2)
76 | in add (big1, big2)
77 |
78 | (* Constructeur propre a la sousatraction qui va
79 | permettre de ne pas effectuer la retenue *)
80 | let bigint_sum_for_sous big1 big2 =
81 | let rec add = function
82 | [], r | r, [] -> r
83 | | d1 :: r1, d2 :: r2 ->
84 | let s = d1 + d2 in
85 | s :: add (r1, r2)
86 | in add (big1, big2)
87 |
88 | (* On preferera a > b en abs et on aura toujours*)
89 | let rec sous = function
90 | [], [] -> []
91 | | [], r | r, [] -> r
92 | | d1 :: r1, d2 :: r2 ->
93 | if d1 >= d2 then
94 | (d1 - d2) :: sous(r1, r2)
95 | else
96 | (d1 + 10 - d2) :: sous (r1, (bigint_sum_for_sous [1] r2))
97 |
98 | let sous a = sous a |> nettoyer_zero
99 |
100 | (** renvoie ga + gb *)
101 | let additioner ga gb =
102 | match ga, gb with
103 | (true, b), (false, d) | (false, d), (true, b) ->
104 | if comparer_nbr_abs b d = -1 then
105 | true, sous (b, d)
106 | else
107 | false, sous (d, b)
108 | | (a, b), (_ (* = a *), d) -> a, bigint_sum b d
109 |
110 | (** renvoie ga - gb *)
111 | let soustraire ga gb =
112 | match ga, gb with
113 | (true, b), (true, d) | (false, d), (false, b) ->
114 | if comparer_nbr_abs b d = -1 then
115 | true, sous (b, d)
116 | else
117 | false, sous (d, b)
118 | | (a, b), (_ (* not a *), d) -> a, bigint_sum b d
119 |
120 |
121 | let bigint_mult big n =
122 | if n < 0 then
123 | invalid_arg "bigint_mult: negative multiplier"
124 | else
125 | let rec mult n = function
126 | [], 0 -> []
127 | | [], carry -> (* bigint_of_int *) [carry]
128 | | d :: r, carry ->
129 | let res = n * d + carry in
130 | (res mod 10) :: mult n (r, res / 10)
131 | in
132 | match n with
133 | 0 -> []
134 | | 1 -> big
135 | | n -> mult n (big, 0)
136 |
137 |
138 | let bigint_times big1 big2 =
139 | let rec mult = function
140 | [], _ | _, [] -> []
141 | | 0 :: r, big | big, 0 :: r -> 0 :: mult (r, big)
142 | | 1 :: [], big | big, 1 :: [] -> big
143 | | 1 :: r, big | big, 1 :: r -> bigint_sum big (0 :: mult (r, big))
144 | | d :: r, big -> bigint_sum (bigint_mult big d) (0 :: mult (r, big))
145 | in mult (big1, big2)
146 |
147 | (** renvoie ga * gb *)
148 | let multiplier ga gb =
149 | match ga, gb with
150 | (a, b), (c, d) when a = c -> false, bigint_times b d
151 | | (_, b), (_, d) -> true, bigint_times b d
152 |
153 | let abaisser a e ret =
154 | let rec abaisser a n =
155 | let cmp = comparer_nbr_abs a e in
156 | if cmp = 1 then
157 | a, n
158 | else
159 | abaisser (sous (a, e)) (n + 1)
160 | in let a, n = abaisser a 0 in
161 | a, n :: ret
162 |
163 | let rec div_mul a e =
164 | let cmp = comparer_nbr_abs a e in
165 | if cmp = 1 then
166 | a, []
167 | else
168 | let a, n = div_mul a (0 :: e) in
169 | abaisser a e n
170 |
171 | let div_eucl = function
172 | _, (_, []) -> raise Division_by_zero
173 | | (a, b), (c, d) ->
174 | let m, div = div_mul b d in
175 | (a, m), (a <> c, div)
176 |
177 |
178 | let div_eucl_fix = function
179 | _, (_, []) -> raise Division_by_zero
180 | | (false as a, b), (c, d) ->
181 | let m, div = div_mul b d in
182 | (a, m), (a <> c, div)
183 | | (true as a, b), (c, d) ->
184 | let m, div = div_mul b d in
185 | additioner (a, m) (false, d), additioner (a <> c, div) (not c, [1])
186 |
187 | (** renvoie ga / gb où ga est multiple de gb *)
188 | let diviser_multiple ((a, _) as ga) ((c, _) as gb) =
189 | let _, (s, div) = div_eucl (ga, gb) in
190 | if a then
191 | additioner (a <> c, div) (not c, [1])
192 | else
193 | s, div
194 |
195 | (** renvoie le reste de la division euclidienne de ga par gb *)
196 | let modulo ((a, _) as ga) ((_, d) as gb) =
197 | let (s, m), _ = div_eucl (ga, gb) in
198 | if a then
199 | additioner (a, m) (false, d)
200 | else
201 | s, m
202 |
203 | (** renvoie pgcd(ga, gb) *)
204 | let rec pgcd ga gb =
205 | let ga, gb =
206 | if comparer ga gb = 1 (*ga < gb*) then
207 | gb, ga
208 | else
209 | ga, gb
210 | in if gb = zero then
211 | ga
212 | else
213 | pgcd gb (modulo ga gb)
214 |
215 | (** renvoie (nominateur, dénominateur) de la fraction ga / gb *)
216 | let diviser ga gb =
217 | let gc = pgcd ga gb in
218 | diviser_multiple ga gc, diviser_multiple gb gc
219 |
220 | (** renvoie le grandentier à partir de sa représentation textuelle *)
221 | let cse_rec a n =
222 | let n = n - 1 in
223 | let rec abc acc i =
224 | if i = n then
225 | List.rev acc
226 | else
227 | abc ((int_of_char a.[i]) - 48 :: acc) (i - 1)
228 | in abc [] (String.length a - 1) |> nettoyer_zero
229 |
230 | let grandentier_depuis_texte sa =
231 | if sa.[0] = '-' then
232 | true, cse_rec sa 1
233 | else if sa.[0] = '+' then
234 | false, cse_rec sa 1
235 | else
236 | false, cse_rec sa 0
237 |
238 | (* A QUE COUCOU BOP*)
239 | (*Convertit basiquement le nombre*)
240 | let textedechiffre ga =
241 | let rec tdc acc = function
242 | [] -> acc
243 | | e :: ga -> (tdc [@tailcall]) ((string_of_int e) ^ acc) ga
244 | in tdc "" ga
245 |
246 | (** renvoie la représentation textuelle d'un grandentier *)
247 | let texte_depuis_grandentier (a, b) =
248 | if b = [] then
249 | "0"
250 | else if a then
251 | "-" ^ textedechiffre b
252 | else
253 | textedechiffre b
254 |
--------------------------------------------------------------------------------
/src/modules/grandEntier_on.mli:
--------------------------------------------------------------------------------
1 | type grandentier = bool * int list
2 | val zero : grandentier
3 | val unit : grandentier
4 | val est_negatif : grandentier -> bool
5 | val neg : grandentier -> grandentier
6 | val comparer : grandentier -> grandentier -> int
7 | val additioner : grandentier -> grandentier -> grandentier
8 | val soustraire : grandentier -> grandentier -> grandentier
9 | val multiplier : grandentier -> grandentier -> grandentier
10 | val pgcd : grandentier -> grandentier -> grandentier
11 | val diviser_multiple : grandentier -> grandentier -> grandentier
12 | val diviser : grandentier -> grandentier -> grandentier * grandentier
13 | val grandentier_depuis_texte : string -> grandentier
14 | val texte_depuis_grandentier : grandentier -> string
15 |
--------------------------------------------------------------------------------
/src/modules/grandNum_on.ml:
--------------------------------------------------------------------------------
1 | type num =
2 | E of GrandEntier_on.grandentier
3 | | R of GrandReel_on.grandreel
4 | | Q of GrandRationnel_on.grandrationnel
5 |
6 | let power c =
7 | let rec p i = function
8 | 0 -> i
9 | | c -> p (0 :: i) (c - 1)
10 | in p [1] c
11 |
12 | let rec up (a, b, c) =
13 | if c <= 0 then
14 | a, b, [1]
15 | else
16 | up (a, 0 :: b, c - 1)
17 |
18 | let q_depuis_r (a, b, c) =
19 | if c = 0 then
20 | a, b, [1]
21 | else if c > 0 then
22 | up (a, b, c)
23 | else
24 | a, b, power ~-c
25 |
26 | let zero = E (GrandEntier_on.grandentier_depuis_texte "0")
27 |
28 | let unit = E (GrandEntier_on.grandentier_depuis_texte "1")
29 |
30 | let vers_grandentier = function
31 | E _ as e -> e
32 | | R (_, [], _) -> zero
33 | | R (s, mantisse, exp) as r ->
34 | if exp > 0 then
35 | let s, mantisse, exp = up (s, mantisse, exp) in
36 | if exp = [1] then (* Should always be true *)
37 | E (s, mantisse)
38 | else
39 | r
40 | else
41 | r
42 | | Q (_, [], _) -> zero
43 | | Q (_, _, []) -> raise Division_by_zero
44 | | Q (signe, nom, [1]) -> E (signe, nom)
45 | | Q _ as q -> q
46 |
47 | let multiplier = function
48 | E e1, E e2 -> E (GrandEntier_on.multiplier e1 e2)
49 | | R r1, R r2 -> R (GrandReel_on.multiplier r1 r2)
50 | | Q q1, Q q2 -> Q (GrandRationnel_on.multiplier q1 q2)
51 | | R r2, E (signe, e1) -> R (GrandReel_on.multiplier (signe, e1, 0) r2)
52 | | E (signe, e1), R r2 -> R (GrandReel_on.multiplier (signe, e1, 0) r2)
53 | | E (signe, e1), Q q1 -> Q (GrandRationnel_on.multiplier q1 (signe, e1, [1]))
54 | | Q q1, E (signe, e1) -> Q (GrandRationnel_on.multiplier q1 (signe, e1, [1]))
55 | | R r1, Q q1 -> Q (GrandRationnel_on.multiplier q1 (q_depuis_r r1))
56 | | Q q1, R r1 -> Q (GrandRationnel_on.multiplier q1 (q_depuis_r r1))
57 |
58 | let multiplier e = multiplier e |> vers_grandentier
59 |
60 | let soustraire = function
61 | E e1, E e2 -> E (GrandEntier_on.soustraire e1 e2)
62 | | R r1, R r2 -> R (GrandReel_on.soustraire r1 r2)
63 | | Q q1, Q q2 -> Q (GrandRationnel_on.soustraire q1 q2)
64 | | R r2, E (signe, e1) -> R (GrandReel_on.soustraire (signe, e1, 0) r2)
65 | | E (signe, e1), R r2 -> R (GrandReel_on.soustraire (signe, e1, 0) r2)
66 | | E (signe, e1), Q q1 -> Q (GrandRationnel_on.soustraire q1 (signe, e1, [1]))
67 | | Q q1, E (signe, e1) -> Q (GrandRationnel_on.soustraire q1 (signe, e1, [1]))
68 | | R r1, Q q1 -> Q (GrandRationnel_on.soustraire q1 (q_depuis_r r1))
69 | | Q q1, R r1 -> Q (GrandRationnel_on.soustraire q1 (q_depuis_r r1))
70 |
71 | let soustraire e = soustraire e |> vers_grandentier
72 |
73 | let additioner = function
74 | E e1, E e2 -> E (GrandEntier_on.additioner e1 e2)
75 | | R r1, R r2 -> R (GrandReel_on.additioner r1 r2)
76 | | Q q1, Q q2 -> Q (GrandRationnel_on.additioner q1 q2)
77 | | R r2, E (signe, e1) -> R (GrandReel_on.additioner (signe, e1, 0) r2)
78 | | E (signe, e1), R r2 -> R (GrandReel_on.additioner (signe, e1, 0) r2)
79 | | E (signe, e1), Q q1 -> Q (GrandRationnel_on.additioner q1 (signe, e1, [1]))
80 | | Q q1, E (signe, e1) -> Q (GrandRationnel_on.additioner q1 (signe, e1, [1]))
81 | | R r1, Q q1 -> Q (GrandRationnel_on.additioner q1 (q_depuis_r r1))
82 | | Q q1, R r1 -> Q (GrandRationnel_on.additioner q1 (q_depuis_r r1))
83 |
84 | let additioner e = additioner e |> vers_grandentier
85 |
86 | let diviser = function
87 | E (signe1, e1), E (signe2, e2) -> Q (signe1 <> signe2, e1, e2)
88 | | R r1, R r2 -> Q (GrandRationnel_on.diviser (q_depuis_r r1) (q_depuis_r r2))
89 | | Q q1, Q q2 -> Q (GrandRationnel_on.diviser q1 q2)
90 | | R r2, E (signe, e1) -> Q (GrandRationnel_on.diviser (signe, e1, [1]) (q_depuis_r r2))
91 | | E (signe, e1), R r2 -> Q (GrandRationnel_on.diviser (signe, e1, [1]) (q_depuis_r r2))
92 | | E (signe, e1), Q q1 -> Q (GrandRationnel_on.diviser q1 (signe, e1, [1]))
93 | | Q q1, E (signe, e1) -> Q (GrandRationnel_on.diviser q1 (signe, e1, [1]))
94 | | R r1, Q q1 -> Q (GrandRationnel_on.diviser q1 (q_depuis_r r1))
95 | | Q q1, R r1 -> Q (GrandRationnel_on.diviser q1 (q_depuis_r r1))
96 |
97 | let diviser e = diviser e |> vers_grandentier
98 |
99 | let opposer = function
100 | E (signe, e1) -> E (not signe, e1)
101 | | Q (signe, q1, q2) -> Q (not signe, q1, q2)
102 | | R (signe, r, exp) -> R (not signe, r, exp)
103 |
104 | let opposer e = opposer e |> vers_grandentier
105 |
106 | let inverser = function
107 | E (signe, e1) -> Q (signe, [1], e1)
108 | | Q (signe, q1, q2) -> Q (signe, q2, q1)
109 | | R r1 ->
110 | let a, b, c = q_depuis_r r1 in
111 | Q (a, c, b)
112 |
113 | let inverser e = inverser e |> vers_grandentier
114 |
115 | let texte_depuis_num = function
116 | E e1 -> GrandEntier_on.texte_depuis_grandentier e1
117 | | R r1 -> GrandReel_on.texte_depuis_grandreel r1
118 | | Q (signe, q1, q2) ->
119 | let q1 = GrandEntier_on.texte_depuis_grandentier (false, q1)
120 | and q2 = GrandEntier_on.texte_depuis_grandentier (false, q2) in
121 | let q = q1 ^ "/" ^ q2 in
122 | if signe then
123 | "-" ^ q
124 | else
125 | q
126 |
127 | let est_negatif = function
128 | E (signe, _) -> signe
129 | | Q (signe, _, _) -> signe
130 | | R (signe, _, _) -> signe
131 |
--------------------------------------------------------------------------------
/src/modules/grandNum_on.mli:
--------------------------------------------------------------------------------
1 | type num =
2 | E of GrandEntier_on.grandentier
3 | | R of GrandReel_on.grandreel
4 | | Q of GrandRationnel_on.grandrationnel
5 | val zero : num
6 | val unit : num
7 | val power : int -> int list
8 | val up : 'a * int list * int -> 'a * int list * int list
9 | val q_depuis_r : GrandReel_on.grandreel -> GrandRationnel_on.grandrationnel
10 | val multiplier : num * num -> num
11 | val soustraire : num * num -> num
12 | val additioner : num * num -> num
13 | val diviser : num * num -> num
14 | val opposer : num -> num
15 | val inverser : num -> num
16 | val texte_depuis_num : num -> string
17 | val est_negatif : num -> bool
18 |
--------------------------------------------------------------------------------
/src/modules/grandRationnel_on.ml:
--------------------------------------------------------------------------------
1 | open GrandEntier_on
2 |
3 | type grandrationnel = bool * int list * int list
4 |
5 | let additioner (a, b, c) (d, e, f) =
6 | let z = multiplier (a, b) (false, f)
7 | and elie = multiplier (false, c) (d, e)
8 | and travail = multiplier (false, c) (false, f) in
9 | let alex, gautier = additioner z elie in
10 | let (_, quentin), (_, tropdeu) = diviser (alex, gautier) travail in
11 | alex, quentin, tropdeu
12 |
13 | let soustraire (a, b, c) (d, e, f) =
14 | additioner (a, b, c) (not d, e, f)
15 |
16 | let multiplier (a, b, c) (d, e, f) =
17 | let thomas = multiplier (false, b) (false, e)
18 | and mouton = multiplier (false, c) (false, f) in
19 | let (_, x), (_, i) = diviser thomas mouton in
20 | a <> d, x, i
21 |
22 | let diviser (a, b, c) (d, e, f) =
23 | multiplier (a, b, c) (d, f, e)
24 |
--------------------------------------------------------------------------------
/src/modules/grandReel_on.ml:
--------------------------------------------------------------------------------
1 | open GrandEntier_on
2 |
3 | (** grandreel est un tuple [(signe négatif, \[unité, dizaine, centaine, ...\], exposant base 10)]
4 | [-1,23] correspond à [(true, \[3; 2; 1\], -2)] *)
5 | type grandreel = bool * int list * int
6 |
7 | (** zero de grandreel *)
8 | let zero = false, [], 0
9 |
10 | (** unité de grandreel *)
11 | let unit = false, [1], 0
12 |
13 | (** renvoie [grandreel < 0] *)
14 | let est_negatif (s, _, _) = s
15 |
16 | (* let is_nul (a, b, c) = b = [] *)
17 |
18 | (** renvoie l'oposé *)
19 | let neg = function
20 | _, [], _ -> false, [], 0
21 | | s, m, e -> not s, m, e
22 |
23 |
24 | let remove a =
25 | let rec r0 = function
26 | [] -> []
27 | | 0 :: c -> r0 c
28 | | c -> List.rev c
29 | in r0 (List.rev a)
30 |
31 |
32 | let rec powerup = function
33 | _, [], _ -> false, [], 0
34 | | s, 0 :: b, c -> powerup (s, b, c + 1)
35 | | s, e :: b, c -> s, e :: b, c
36 |
37 |
38 | (*
39 | Fonction Auxiliaire qui va mettre les deux valeurs sur la meme puissance
40 | On choisira toujours la plus grande
41 | *)
42 | let reunir_puissance ga gb =
43 | let rec r_p ga gb =
44 | let sa, va, a = ga
45 | and sb, vb, b = gb in
46 | if a = b then
47 | ga, gb
48 | else if a < b then
49 | r_p (sa, va, a) (sb, 0 :: vb, b - 1)
50 | else
51 | r_p (sa, 0 :: va, a - 1) (sb, vb, b)
52 | in r_p ga gb
53 |
54 | (** 1 si ga < gb sinon 0 si ga = gb sinon -1 *)
55 | (* 1 : gb > ga
56 | 0 : ga = gb
57 | -1 : ga > gb*)
58 |
59 | let comparer ga gb =
60 | let (a, b, _), (d, e, _) = reunir_puissance ga gb in
61 | comparer (a, b) (d, e)
62 |
63 | (** renvoie ga + gb *)
64 | let additioner ga gb =
65 | let (a, b, c), (d, e, _) = reunir_puissance ga gb in
66 | let a, b = additioner (a, b) (d, e) in
67 | powerup (a, remove b, c)
68 |
69 | (** renvoie ga - gb *)
70 | let soustraire ga gb =
71 | let (a, b, c), (d, e, _) = reunir_puissance ga gb in
72 | let a, b = soustraire (a, b) (d, e) in
73 | powerup (a, remove b, c)
74 |
75 | (** renvoie ga * gb *)
76 | let multiplier (a, b, c) (d, e, f) =
77 | let a, b = multiplier (a, b) (d, e) in
78 | powerup (a, remove b, c + f)
79 |
80 | (** renvoie ga / gb *)
81 | let diviser (a, b, c) (d, e, f) =
82 | let () =
83 | if e = [] then (* / 0 *)
84 | failwith "Pas de mechant mot :("
85 | in let signe = b <> [] (* 0 / a -> + *) && a <> d in
86 | let b = [] in
87 | powerup (signe, remove b, c - f), powerup (signe, remove b, c - f)
88 |
89 | let grandReel_depuis_texte_transfo start ga =
90 | let max = String.length ga in
91 | let rec grdt (a, b, c) cpt =
92 | if cpt = max then
93 | b, c
94 | else
95 | let next =
96 | match a, ga.[cpt] with
97 | _, (',' | '.') -> true, b, c
98 | | true, cha -> true, (int_of_char cha - 48) :: b, c - 1
99 | | false, cha -> false, (int_of_char cha - 48) :: b, c
100 | in grdt next (cpt + 1)
101 | in grdt (false, [], 0) start
102 |
103 |
104 | let grandreel_depuis_texte sa =
105 | let signe, transfo =
106 | match sa.[0] with (* sa is not "" *)
107 | '-' -> true, grandReel_depuis_texte_transfo 1
108 | | '+' -> false, grandReel_depuis_texte_transfo 1
109 | | _ -> false, grandReel_depuis_texte_transfo 0
110 | in let mantisse, exposant = transfo sa in
111 | (signe, remove mantisse, exposant) |> powerup
112 |
113 | (*Convertit basiquement le nombre*)
114 | let textedechiffre ga =
115 | let rec tdc = function
116 | [] -> ""
117 | | e :: ga -> tdc ga ^ (string_of_int e)
118 | in tdc ga
119 |
120 | (** renvoie la représentation textuelle d'un grandentier *)
121 | let texte_depuis_grandentier ga =
122 | let a, b = ga in
123 | if a then
124 | "-" ^ textedechiffre b
125 | else
126 | textedechiffre b
127 |
128 | let rec ajouterdes0 texte nbr =
129 | if nbr = 0 then
130 | texte
131 | else
132 | ajouterdes0 (texte ^ "0") (nbr - 1)
133 |
134 | let rec tdgcs = function
135 | [], _ -> ""
136 | | a, 0 -> tdgcs (a, 1) ^ ","
137 | | e :: a, b -> tdgcs (a, b + 1) ^ string_of_int e
138 |
139 | let texte_depuis_grandreel_cas_neg (a, b, c) =
140 | let texte = tdgcs (b, c) in
141 | if a then
142 | "-" ^ texte
143 | else
144 | texte
145 |
146 | let texte_depuis_grandreel = function
147 | _, [], _ -> "0"
148 | | a, b, 0 -> texte_depuis_grandentier (a, b)
149 | | a, b, c when c > 0 -> ajouterdes0 (texte_depuis_grandentier (a, b)) c
150 | | ga -> texte_depuis_grandreel_cas_neg ga
151 |
152 | (*
153 | let t_depart = "42,24"
154 | let ga = grandreel_depuis_texte t_depart
155 | let resultat_correct = texte_depuis_grandreel ga = t_depart
156 | *)
157 |
--------------------------------------------------------------------------------
/src/modules/grandReel_on.mli:
--------------------------------------------------------------------------------
1 | type grandreel = bool * int list * int
2 | val zero : grandreel
3 | val unit : grandreel
4 | val est_negatif : grandreel -> bool
5 | val neg : grandreel -> grandreel
6 | val comparer : grandreel -> grandreel -> int
7 | val additioner : grandreel -> grandreel -> grandreel
8 | val soustraire : grandreel -> grandreel -> grandreel
9 | val multiplier : grandreel -> grandreel -> grandreel
10 | val diviser : grandreel -> grandreel -> grandreel * grandreel
11 | val grandreel_depuis_texte : string -> grandreel
12 | val texte_depuis_grandreel : grandreel -> string
13 |
--------------------------------------------------------------------------------
/src/modules/matrix.ml:
--------------------------------------------------------------------------------
1 | module type Value = sig
2 | type t
3 |
4 | val zero : t
5 | val unit : t
6 | val symb : string -> t
7 | val neg : t -> t
8 | val est_zero : t -> bool
9 | val depuis_texte : string -> t
10 | val vers_texte : t -> string
11 | val additioner : t -> t -> t
12 | val soustraire : t -> t -> t
13 | val diviser : t -> t -> t
14 | val multiplier : t -> t -> t
15 | val print : t -> unit
16 | end
17 |
18 | module Generic_matrix (V : Value) = struct
19 | type t = V.t array array
20 | type solution_equation =
21 | Erreur of string
22 | | Solution_systeme of (string * V.t) list
23 |
24 | let print = V.print
25 | let init n p = Array.make_matrix n p V.zero
26 | let __protect m = Array.length m > 0 && Array.length m.(0) > 0
27 | let size m =
28 | let h = Array.length m in
29 | if h = 0 then
30 | h, 0
31 | else
32 | h, Array.length m.(0)
33 | let foreach ?(line = function _ -> ()) m f =
34 | if __protect m then
35 | let h, w = size m in
36 | for i = 0 to pred h do
37 | let () =
38 | for j = 0 to pred w do
39 | f i j m.(i).(j)
40 | done
41 | in line m.(i)
42 | done
43 | let print m =
44 | let () =
45 | foreach ~line:(fun _ -> print_char '\n') m (fun _ _ -> V.print)
46 | in print_char '\n'
47 | let foreach2 f m1 m2 =
48 | let (h, w) = size m1 in
49 | if (h, w) = size m2 then
50 | let mres = init h w in
51 | let () = foreach m1 (fun i j e -> mres.(i).(j) <- f e m2.(i).(j)) in
52 | mres
53 | else
54 | failwith (I18n.matrice_mauvaise_dimension ())
55 | let __vide_vers_identite m =
56 | let h, w = size m in
57 | let () =
58 | for i = 0 to pred (min h w) do
59 | m.(i).(i) <- V.unit
60 | done
61 | in m
62 | let identite n =
63 | let mres = init n n in
64 | __vide_vers_identite mres
65 | let additioner m1 m2 = foreach2 V.additioner m1 m2
66 | let soustraire m1 m2 = foreach2 V.soustraire m1 m2
67 | let multiplier m1 m2 =
68 | let (n, p) = size m1
69 | and (p', q) = size m2 in
70 | if p = p' then
71 | let mres = init n q in
72 | let prod_ligne_colonne i j =
73 | let res = ref V.zero in
74 | let () =
75 | for k = 0 to pred p do
76 | res := V.additioner !res (V.multiplier m1.(i).(k) m2.(k).(j))
77 | done
78 | in !res
79 | in let () = foreach mres (fun i j _ -> mres.(i).(j) <- prod_ligne_colonne i j) in
80 | mres
81 | else
82 | failwith "taille mauvaise dimension"
83 | let multiplier_scalaire m scalaire =
84 | let (h, w) = size m in
85 | let mres = init h w in
86 | let () = foreach m (fun i j e -> mres.(i).(j) <- V.multiplier e scalaire) in
87 | mres
88 | module Operation_elementaires = struct
89 | let multiplier_ligne l scalaire =
90 | Array.map (V.multiplier scalaire) l
91 | let additioner_ligne l1 l2 =
92 | Array.mapi (fun k -> V.additioner l2.(k)) l1
93 | let neg_ligne l =
94 | Array.map V.neg l
95 | let echanger_ligne m i j =
96 | let tmp = m.(i) in
97 | let () = m.(i) <- m.(j) in
98 | m.(j) <- tmp
99 | let affecter_ligne m i l =
100 | m.(i) <- l
101 | let comb_lineaire mat (a, i) (b, j) =
102 | Array.mapi (fun k e ->
103 | V.additioner (V.multiplier a e) (V.multiplier b mat.(j).(k)))
104 | mat.(i)
105 | let ajouter_ligne inc mat i w h =
106 | let l = Array.make (w + 1) V.zero in
107 | let () = l.(i) <- V.unit in
108 | let () = l.(w) <- V.symb inc.(i) in
109 | let () = mat := Array.append !mat [| l |] in
110 | incr h
111 | end
112 | let inverser m' =
113 | let h, w = size m' in
114 | let m = init h w in
115 | let () = foreach m' (fun i j e -> m.(i).(j) <- e) in
116 | let n = min h w in
117 | let mres = init w h in
118 | let mres = __vide_vers_identite mres in
119 | let open Operation_elementaires in
120 | let () =
121 | for i = 0 to pred (pred n) do
122 | for j = i + 1 to pred h do
123 | if m.(j).(i) <> V.zero then
124 | let () =
125 | if m.(i).(i) = V.zero then
126 | let () = echanger_ligne m j i in
127 | echanger_ligne mres j i
128 | else
129 | let pivot = m.(i).(i) in
130 | let coeff = V.diviser m.(j).(i) pivot in
131 | let modifier_ligne m =
132 | let ligne = multiplier_ligne m.(i) coeff in
133 | let ligne = neg_ligne ligne in
134 | let () = Printf.printf "%d, %d\n" (Array.length m.(j)) (Array.length ligne) in
135 | let ligne = additioner_ligne m.(j) ligne in
136 | affecter_ligne m j ligne
137 | in let () = modifier_ligne m in
138 | if j < n then
139 | modifier_ligne mres
140 | (* in fact we should empty it *)
141 | in print mres
142 | done
143 | done
144 | in let () = print m in
145 | mres
146 |
147 | let triangle_superieur inc mat h w =
148 | let mat = ref mat
149 | and h = ref h in
150 | let () =
151 | for i = 0 to pred w do
152 | let () =
153 | if i > pred !h then
154 | Operation_elementaires.ajouter_ligne inc mat i w h
155 | in let () =
156 | if V.est_zero !mat.(i).(i) then
157 | let () =
158 | for k = i + 1 to pred !h do
159 | if not (V.est_zero !mat.(k).(i)) then
160 | Operation_elementaires.echanger_ligne !mat i i
161 | done
162 | in if V.est_zero !mat.(i).(i) then
163 | let () = Operation_elementaires.ajouter_ligne inc mat i w h in
164 | Operation_elementaires.echanger_ligne !mat (pred !h) i
165 | in for j = i + 1 to pred !h do
166 | !mat.(j) <- Operation_elementaires.comb_lineaire !mat (!mat.(j).(i), i) (V.neg (!mat.(i).(i)), j)
167 | done
168 | done
169 | in !mat, !h
170 |
171 | let nomalise mat w =
172 | let () =
173 | for i = 0 to pred w do
174 | mat.(i) <- Operation_elementaires.multiplier_ligne mat.(i) (V.diviser V.unit mat.(i).(i))
175 | done
176 | in mat
177 |
178 | let remonte mat w =
179 | let () =
180 | for i = pred w downto 0 do
181 | for k = i - 1 downto 0 do
182 | mat.(k) <- Operation_elementaires.comb_lineaire mat (V.neg mat.(k).(i), i) (mat.(i).(i), k)
183 | done
184 | done
185 | in mat
186 |
187 | let contractition_presente mat w h =
188 | let resultat = ref false in
189 | let () =
190 | for i = w to pred h do
191 | resultat := not (V.est_zero mat.(i).(w)) || !resultat
192 | done
193 | in !resultat
194 |
195 | let resoudre_sys mat w h inc =
196 | let mat, h = triangle_superieur inc mat h w in
197 | let mat = nomalise mat w in
198 | let mat = remonte mat w in
199 | mat, w, h, inc
200 |
201 | let solveur mat w h inc =
202 | let mat = Array.map (Array.map V.depuis_texte) mat in
203 | let mat, w, h, inc = resoudre_sys mat w h inc in
204 | if contractition_presente mat w h then
205 | Erreur (I18n.contractition_presente ())
206 | else
207 | Solution_systeme ((Array.mapi (fun i e -> (e, mat.(i).(w))) inc) |> Array.to_list)
208 | end
209 |
210 | module Test_int = struct
211 | type t = int
212 |
213 | let zero = 0
214 | let unit = 1
215 | let symb _ = unit
216 | let neg = ( ~- )
217 | let est_zero = (=) 0
218 | let depuis_texte = int_of_string
219 | let vers_texte = string_of_int
220 | let additioner = ( + )
221 | let soustraire = ( - )
222 | let diviser = ( / )
223 | let multiplier = ( * )
224 | let print = Printf.printf "%5d"
225 | end
226 |
227 | module Test_int_matrix = Generic_matrix(Test_int)
228 |
229 | module Test_float = struct
230 | type t = float
231 |
232 | let zero = 0.
233 | let unit = 1.
234 | let symb _ = unit
235 | let neg = ( ~-. )
236 | let est_zero a = -0.0001 < a && a < 0.0001
237 | let depuis_texte = float_of_string
238 | let vers_texte = string_of_float
239 | let additioner = ( +. )
240 | let soustraire = ( -. )
241 | let diviser = ( /. )
242 | let multiplier = ( *. )
243 | let print = Printf.printf "%10.6f"
244 | end
245 |
246 | module Test_float_matrix = Generic_matrix(Test_float)
247 |
--------------------------------------------------------------------------------
/src/modules/matrix.mli:
--------------------------------------------------------------------------------
1 | module type Value =
2 | sig
3 | type t
4 | val zero : t
5 | val unit : t
6 | val symb : string -> t
7 | val neg : t -> t
8 | val est_zero : t -> bool
9 | val depuis_texte : string -> t
10 | val vers_texte : t -> string
11 | val additioner : t -> t -> t
12 | val soustraire : t -> t -> t
13 | val diviser : t -> t -> t
14 | val multiplier : t -> t -> t
15 | val print : t -> unit
16 | end
17 | module Generic_matrix :
18 | functor (V : Value) ->
19 | sig
20 | type t = V.t array array
21 | type solution_equation =
22 | Erreur of string
23 | | Solution_systeme of (string * V.t) list
24 | val init : int -> int -> V.t array array
25 | val __protect : 'a array array -> bool
26 | val size : 'a array array -> int * int
27 | val foreach :
28 | ?line:('a array -> unit) ->
29 | 'a array array -> (int -> int -> 'a -> unit) -> unit
30 | val print : V.t array array -> unit
31 | val foreach2 :
32 | ('a -> 'b -> V.t) ->
33 | 'a array array -> 'b array array -> V.t array array
34 | val __vide_vers_identite : V.t array array -> V.t array array
35 | val identite : int -> V.t array array
36 | val additioner : V.t array array -> V.t array array -> V.t array array
37 | val soustraire : V.t array array -> V.t array array -> V.t array array
38 | val multiplier : V.t array array -> V.t array array -> V.t array array
39 | val multiplier_scalaire : V.t array array -> V.t -> V.t array array
40 | module Operation_elementaires :
41 | sig
42 | val multiplier_ligne : V.t array -> V.t -> V.t array
43 | val additioner_ligne : V.t array -> V.t array -> V.t array
44 | val neg_ligne : V.t array -> V.t array
45 | val echanger_ligne : 'a array -> int -> int -> unit
46 | val affecter_ligne : 'a array -> int -> 'a -> unit
47 | end
48 | val inverser : V.t array array -> V.t array array
49 | val solveur : string array array -> int -> int -> string array -> solution_equation
50 | end
51 | module Test_int :
52 | sig
53 | type t = int
54 | val zero : int
55 | val unit : int
56 | val symb : string -> t
57 | val neg : int -> int
58 | val est_zero : int -> bool
59 | val depuis_texte : string -> int
60 | val vers_texte : int -> string
61 | val additioner : int -> int -> int
62 | val soustraire : int -> int -> int
63 | val diviser : int -> int -> int
64 | val multiplier : int -> int -> int
65 | val print : int -> unit
66 | end
67 | module Test_int_matrix :
68 | sig
69 | type t = Test_int.t array array
70 | type solution_equation =
71 | Erreur of string
72 | | Solution_systeme of (string * Test_int.t) list
73 | val init : int -> int -> Test_int.t array array
74 | val __protect : 'a array array -> bool
75 | val size : 'a array array -> int * int
76 | val foreach :
77 | ?line:('a array -> unit) ->
78 | 'a array array -> (int -> int -> 'a -> unit) -> unit
79 | val print : Test_int.t array array -> unit
80 | val foreach2 :
81 | ('a -> 'b -> Test_int.t) ->
82 | 'a array array -> 'b array array -> Test_int.t array array
83 | val __vide_vers_identite :
84 | Test_int.t array array -> Test_int.t array array
85 | val identite : int -> Test_int.t array array
86 | val additioner :
87 | Test_int.t array array ->
88 | Test_int.t array array -> Test_int.t array array
89 | val soustraire :
90 | Test_int.t array array ->
91 | Test_int.t array array -> Test_int.t array array
92 | val multiplier :
93 | Test_int.t array array ->
94 | Test_int.t array array -> Test_int.t array array
95 | val multiplier_scalaire :
96 | Test_int.t array array -> Test_int.t -> Test_int.t array array
97 | module Operation_elementaires :
98 | sig
99 | val multiplier_ligne :
100 | Test_int.t array -> Test_int.t -> Test_int.t array
101 | val additioner_ligne :
102 | Test_int.t array -> Test_int.t array -> Test_int.t array
103 | val neg_ligne : Test_int.t array -> Test_int.t array
104 | val echanger_ligne : 'a array -> int -> int -> unit
105 | val affecter_ligne : 'a array -> int -> 'a -> unit
106 | end
107 | val inverser : Test_int.t array array -> Test_int.t array array
108 | val solveur : string array array -> int -> int -> string array -> solution_equation
109 | end
110 | module Test_float :
111 | sig
112 | type t = float
113 | val zero : t
114 | val unit : t
115 | val symb : string -> t
116 | val neg : float -> float
117 | val est_zero : float -> bool
118 | val depuis_texte : string -> float
119 | val vers_texte : float -> string
120 | val additioner : float -> float -> float
121 | val soustraire : float -> float -> float
122 | val diviser : float -> float -> float
123 | val multiplier : float -> float -> float
124 | val print : float -> unit
125 | end
126 | module Test_float_matrix :
127 | sig
128 | type t = Test_float.t array array
129 | type solution_equation =
130 | Erreur of string
131 | | Solution_systeme of (string * Test_float.t) list
132 | val init : int -> int -> Test_float.t array array
133 | val __protect : 'a array array -> bool
134 | val size : 'a array array -> int * int
135 | val foreach :
136 | ?line:('a array -> unit) ->
137 | 'a array array -> (int -> int -> 'a -> unit) -> unit
138 | val print : Test_float.t array array -> unit
139 | val foreach2 :
140 | ('a -> 'b -> Test_float.t) ->
141 | 'a array array -> 'b array array -> Test_float.t array array
142 | val __vide_vers_identite :
143 | Test_float.t array array -> Test_float.t array array
144 | val identite : int -> Test_float.t array array
145 | val additioner :
146 | Test_float.t array array ->
147 | Test_float.t array array -> Test_float.t array array
148 | val soustraire :
149 | Test_float.t array array ->
150 | Test_float.t array array -> Test_float.t array array
151 | val multiplier :
152 | Test_float.t array array ->
153 | Test_float.t array array -> Test_float.t array array
154 | val multiplier_scalaire :
155 | Test_float.t array array -> Test_float.t -> Test_float.t array array
156 | module Operation_elementaires :
157 | sig
158 | val multiplier_ligne :
159 | Test_float.t array -> Test_float.t -> Test_float.t array
160 | val additioner_ligne :
161 | Test_float.t array -> Test_float.t array -> Test_float.t array
162 | val neg_ligne : Test_float.t array -> Test_float.t array
163 | val echanger_ligne : 'a array -> int -> int -> unit
164 | val affecter_ligne : 'a array -> int -> 'a -> unit
165 | end
166 | val inverser : Test_float.t array array -> Test_float.t array array
167 | val solveur : string array array -> int -> int -> string array -> solution_equation
168 | end
169 |
--------------------------------------------------------------------------------
/src/noyau/ancien_moteur.ml:
--------------------------------------------------------------------------------
1 | open Lien
2 | open Type
3 |
4 | let rec additioner = function
5 | [], [] -> failwith "Chut OCaml: additioner rien du tout ?"
6 | | [], e :: l -> additioner ([eval e], l)
7 | | acc, [] -> List.rev acc
8 | | e :: acc, (a :: l) ->
9 | match eval e, eval a with
10 | | Entier a, Variable e -> additioner (Variable e :: acc, Entier a :: l)
11 | | Entier e, Entier a ->
12 | let res = Entier (GrandEntier.additioner e a) in
13 | additioner (res :: acc, l)
14 | | e, a -> additioner (a :: e :: acc, l)
15 |
16 | and multiplier = function
17 | [], [] -> failwith "Chut OCaml: multiplier rien du tout ?"
18 | | [], e :: l -> multiplier ([eval e], l)
19 | | acc, [] -> List.rev acc
20 | | e :: acc, Inv a :: l when (match e with Inv _ -> false | _ -> true) ->
21 | multiplier (acc, Inv a :: e :: l)
22 | | e :: acc, (a :: l) ->
23 | match eval e, eval a with
24 | | Entier a, Variable e -> multiplier (Variable e :: acc, Entier a :: l)
25 | | Entier e, Entier a ->
26 | let res = Entier (GrandEntier.multiplier e a)
27 | in multiplier (res :: acc, l)
28 | | Entier e, Inv (Entier a) | Inv (Entier a), Entier e ->
29 | (match GrandEntier.diviser e a with
30 | e, x when x = GrandEntier.unit -> multiplier ((Entier e) :: acc, l)
31 | | x, a when x = GrandEntier.unit -> multiplier (acc, Inv (Entier a) :: l)
32 | | e, a -> multiplier ((Entier e) :: Inv (Entier a) :: acc, l))
33 | | Inv (Entier e), Inv (Entier a) ->
34 | let res = GrandEntier.multiplier e a in
35 | multiplier (acc, Inv (Entier res) :: l)
36 | | e, a -> multiplier (a :: e :: acc, l)
37 |
38 | and eval = function
39 | Operation ("+", []) -> failwith "euh il y a un problème"
40 | | Operation ("+", [e]) -> eval e
41 | | Operation ("+", e :: l) ->
42 | let acc = [eval e] in
43 | (match additioner (acc, l) with
44 | [e] -> e
45 | | l -> Operation ("+", l))
46 | | Operation ("*", []) -> failwith "euh il y a un problème"
47 | | Operation ("*", [e]) -> eval e
48 | | Operation ("*", e :: l) ->
49 | let acc = [eval e] in
50 | (match multiplier (acc, l) with
51 | [e] -> e
52 | | l -> Operation ("*", l))
53 | | Neg (Neg e) -> eval e
54 | | a -> a
55 |
56 | type context = expr list
57 |
58 | let empty_context = []
59 |
60 | let evaluate_with_history str context =
61 | let e = eval (Parser.expr_de_texte str) in
62 | Parser.texte_de_expr e, e :: context
63 |
--------------------------------------------------------------------------------
/src/noyau/ancien_moteur.mli:
--------------------------------------------------------------------------------
1 | val eval : Type.expr -> Type.expr
2 |
3 | type context = Type.expr list
4 |
5 | val empty_context: context
6 | val evaluate_with_history: string -> context -> string * context
7 |
--------------------------------------------------------------------------------
/src/noyau/dune:
--------------------------------------------------------------------------------
1 | (library
2 | (name Noyau)
3 | (modules Lien Type Utils Lexer Parser Moteur Nouveau_type Nouveau_lexer Nouveau_parser Ancien_moteur)
4 | (libraries Modules I18n))
5 |
--------------------------------------------------------------------------------
/src/noyau/lexer.ml:
--------------------------------------------------------------------------------
1 | open Utils
2 |
3 | let est_entier t(*exte*) b(*ase*) =
4 | let l(*ongueur*) = String.length t in
5 | let m(*aximum caractere *) = char_of_int (b + 48) in
6 | let rec est_entier i =
7 | i = l
8 | || '0' <= t.[i]
9 | && t.[i] < m
10 | && est_entier (i + 1)
11 | in 2 <= l
12 | && ('-' = t.[0]
13 | || '+' = t.[0])
14 | && est_entier 1
15 | || 1 <= l
16 | &&
17 | est_entier 0
18 |
19 | let est_entier10 t = est_entier t 10
20 |
21 | let est_entier_base t(*exte*) =
22 | let l(*ongueur*) = String.length t in
23 | let i =
24 | try
25 | String.index t '_'
26 | with Not_found -> -1
27 | in i > 0
28 | && let b = int_of_string (String.sub t (i + 1) (l - i - 1)) in
29 | 0 <= b
30 | && b < 11
31 | && (t.[0] = '('
32 | && t.[i - 1] = ')'
33 | && est_entier (String.sub t 1 (i - 2)) b)
34 | || (t.[0] != '('
35 | && t.[i - 1] != ')'
36 | && est_entier (String.sub t 0 i) b)
37 |
38 | let est_variable t(*exte*) =
39 | let l(*ongueur*) = String.length t in
40 | let rec est_variable i =
41 | i = l
42 | || 'a' <= t.[i] && t.[i] <= 'z'
43 | && est_variable2 (i + 1)
44 | and est_variable2 i =
45 | i = l
46 | || match t.[i] with
47 | '_' -> i + 1 <> l && est_variable2 (i + 1)
48 | | c when 'a' <= c && c <= 'z' -> est_variable2 (i + 1)
49 | | c when 'A' <= c && c <= 'Z' -> est_variable2 (i + 1)
50 | | c when '0' <= c && c <= '9' -> est_variable2 (i + 1)
51 | | '\'' -> est_variable2 (i + 1)
52 | | _ -> false
53 | in l > 0 && est_variable 0
54 |
55 | let est_addition_soustraction t(*exte*) =
56 | contient_texte t ['+'; '-']
57 |
58 | let est_multiplication_division t(*exte*) =
59 | contient_texte t ['*'; '/']
60 |
--------------------------------------------------------------------------------
/src/noyau/lexer.mli:
--------------------------------------------------------------------------------
1 | val est_entier : string -> int -> bool
2 | val est_entier10 : string -> bool
3 | val est_entier_base : string -> bool
4 | val est_variable : string -> bool
5 | val est_addition_soustraction : string -> bool
6 | val est_multiplication_division : string -> bool
7 |
--------------------------------------------------------------------------------
/src/noyau/lien.ml:
--------------------------------------------------------------------------------
1 | module GrandEntier = Modules.GrandEntier_on
2 | module GrandReel = Modules.GrandReel_on
3 | module GrandRationnel = Modules.GrandRationnel_on
4 | module GrandNum = Modules.GrandNum_on
5 |
--------------------------------------------------------------------------------
/src/noyau/moteur.ml:
--------------------------------------------------------------------------------
1 | open Lien
2 |
3 | type context =
4 | Nouveau_type.expr list (* history *)
5 | * (Nouveau_type.affe, Nouveau_type.expr) Hashtbl.t (* definitions *)
6 |
7 | let empty_context = [], Hashtbl.create 20
8 |
9 | let remplace_inconnu contexte =
10 | let open Nouveau_type in
11 | let rec ri = function
12 | Var s when Hashtbl.find_opt contexte (Def_Var s) <> None ->
13 | Hashtbl.find contexte (Def_Var s)
14 | (*| Fx (nom, n, _) when Hashtbl.find_opt s (Nouveau_type.Def_Fx (nom, n)) <> None ->
15 | Hashtbl.find s (Nouveau_type.Def_Fx (nom, n)) *)
16 | | T (n, l) -> T (n, List.map ri l)
17 | | Fx (nom, n, l) -> Fx (nom, n, List.map ri l)
18 | | Op (`Multiplication, l) -> Op (`Multiplication, List.map ri l)
19 | | Op (`Addition, l) -> Op (`Addition, List.map ri l)
20 | | Inv e -> Inv (ri e)
21 | | Neg e -> Neg (ri e)
22 | | e -> e
23 | in ri
24 |
25 | let rec eval =
26 | let open Nouveau_type in
27 | function
28 | Inv e ->
29 | (
30 | match eval e with
31 | Inv e -> e
32 | | N (n) -> N (GrandNum.inverser n)
33 | | Neg e -> Neg (Inv e)
34 | | e -> Inv e
35 | )
36 | | Neg e ->
37 | (
38 | match eval e with
39 | Neg e -> e
40 | | N (n) -> N (GrandNum.opposer n)
41 | | e -> Neg e
42 | )
43 | | (C _ | N _ | Var _ ) as e -> e
44 | | T (n, l) -> T (n, List.map eval l)
45 | | Fx ("sin", 1, [C Pi]) -> N (GrandNum.zero)
46 | | Fx (nom, n, l) -> Fx (nom, n, List.map eval l)
47 | | Op (`Addition, l) ->
48 | (
49 | match List.map eval l |> additioner [] with
50 | [] ->
51 | let () = prerr_endline "On additionne rien du tout." in
52 | N (GrandNum.E (GrandEntier.grandentier_depuis_texte "0"))
53 | | [e] -> e
54 | | l -> Op (`Addition, l)
55 | )
56 | | Op (`Multiplication, l) ->
57 | (
58 | match List.map eval l |> multiplier [] with
59 | [] ->
60 | let () = prerr_endline "On multiplie rien du tout." in
61 | N (GrandNum.E (GrandEntier.grandentier_depuis_texte "0"))
62 | | [e] -> e
63 | | l -> Op (`Multiplication, l)
64 | )
65 |
66 | and additioner acc liste_expr =
67 | let open Nouveau_type in
68 | match acc, liste_expr with
69 | acc, Op (`Addition, l) :: l' -> additioner acc (l @ l')
70 | | N n1 :: acc, N n2 :: l ->
71 | let n = GrandNum.additioner (n1, n2) in
72 | additioner acc ((N n) :: l)
73 | | N n :: acc, e :: l -> additioner acc (e :: N n :: l)
74 | | acc, e :: l -> additioner (e :: acc) l
75 | | acc, [] -> List.rev acc
76 |
77 | and multiplier acc liste_expr =
78 | let open Nouveau_type in
79 | match acc, liste_expr with
80 | acc, Op (`Multiplication, l) :: l' -> multiplier acc (l @ l')
81 | | N e :: _, _ when e = GrandNum.zero -> [N (GrandNum.zero)]
82 | | _, N e :: _ when e = GrandNum.zero -> [N (GrandNum.zero)]
83 | | N n1 :: acc, N n2 :: l ->
84 | let n = GrandNum.multiplier (n1, n2) in
85 | multiplier acc ((N n) :: l)
86 | | N n :: acc, e :: l -> multiplier acc (e :: N n :: l)
87 | | C I :: acc, C J :: l ->
88 | multiplier acc ((C K) :: l)
89 | | C J :: acc, C I :: l ->
90 | multiplier acc ((Neg (C K)) :: l)
91 | | acc, e :: l -> multiplier (e :: acc) l
92 | | acc, [] -> List.rev acc
93 |
94 | let rec text_de_multiplication l =
95 | let open Nouveau_type in
96 | let rec boucle acc = function
97 | [] -> acc
98 | | Op (`Addition, l) :: k -> boucle (acc ^ "(" ^ texte_de_addition l ^ ")") k
99 | | Inv (Op (_, _) as e) :: l ->
100 | let e = texte_depuis_expr e in
101 | boucle (acc ^ " / " ^ e) l
102 | | Inv e :: l -> boucle (acc ^ " / " ^ (texte_depuis_expr e)) l
103 | | e :: l -> boucle (acc ^ " * " ^ (texte_depuis_expr e)) l
104 | in match l with
105 | [] -> boucle "" l
106 | | Op (`Addition, l) :: k -> boucle ("(" ^ texte_de_addition l ^ ")") k
107 | | Inv (Op (_, _) as e) :: l ->
108 | let e = texte_depuis_expr e in
109 | boucle ("1 / " ^ e) l
110 | | Inv e :: l -> boucle ("1 / " ^ (texte_depuis_expr e)) l
111 | | e :: l -> boucle (texte_depuis_expr e) l
112 |
113 | and texte_de_addition l =
114 | let rec boucle acc = function
115 | [] -> acc
116 | | e :: l ->
117 | let e = texte_depuis_expr e in
118 | if e.[0] = '-' then
119 | boucle (acc ^ e) l
120 | else
121 | boucle (acc ^ " + " ^ e) l
122 | in match l with
123 | [] -> boucle "" l
124 | | e :: l -> boucle (texte_depuis_expr e) l
125 |
126 | and text_depuis_expr_liste sep l =
127 | "(" ^ String.concat sep (List.map texte_depuis_expr l) ^ ")"
128 |
129 | and texte_depuis_expr =
130 | let open Nouveau_type in
131 | let open Lien in
132 | function
133 | N n ->
134 | let e = GrandNum.texte_depuis_num n in
135 | if GrandNum.est_negatif n then
136 | "(" ^ e ^ ")"
137 | else
138 | e
139 | | C Pi -> "pi"
140 | | C I -> "i"
141 | | C J -> "j"
142 | | C K -> "k"
143 | | Var s -> s
144 | | T (_, l) -> (text_depuis_expr_liste ";" l)
145 | | Fx (nom, _, l) -> nom ^ (text_depuis_expr_liste ";" l)
146 | | Op (`Multiplication, l) -> text_de_multiplication l
147 | | Op (`Addition, l) -> texte_de_addition l
148 | | Inv e -> " / " ^ texte_depuis_expr e
149 | | Neg e -> "-" ^ texte_depuis_expr e
150 |
151 | let evaluate_with_history s context =
152 | let history, def = context in
153 | let open Nouveau_parser in
154 | match parse s with
155 | Erreur (s, _ (* TODO: convert l *)) -> s, context
156 | | Expression e ->
157 | let e = Nouveau_type.expr_depuis_expression e in
158 | let e = remplace_inconnu def e in
159 | let e = eval e in
160 | texte_depuis_expr e, (e :: history, def)
161 | | Definition l ->
162 | let l = List.map (function
163 | a, e ->
164 | let a = Nouveau_type.affe_depuis_affectable a
165 | and e = Nouveau_type.expr_depuis_expression e in
166 | let e = remplace_inconnu def e in
167 | let e = eval e in
168 | a, e) l
169 | in let () = List.iter (fun (a, e) -> Hashtbl.add def a e) l in
170 | I18n.definition_valide (), (history, def)
171 |
172 |
173 | module Expr = struct
174 | open Nouveau_type
175 | type t = expr
176 |
177 | let zero = N (GrandNum.zero)
178 | let unit = N (GrandNum.unit)
179 | let symb s = Var s
180 | let neg e = eval (Neg e)
181 | let est_zero a = a = N (GrandNum.zero)
182 | let depuis_texte s =
183 | match Nouveau_parser.parse s with
184 | Expression e ->
185 | let e = Nouveau_type.expr_depuis_expression e in
186 | eval e
187 | | Erreur (s, _ (* TODO: convert l *)) ->
188 | failwith (s)
189 | | _ -> failwith (I18n.definition_non_autorise ())
190 | let vers_texte = texte_depuis_expr
191 | let additioner a b = eval (Op (`Addition, [a; b]))
192 | let soustraire a b = eval (Op (`Addition, [a; Neg b]))
193 | let diviser a b = eval (Op (`Multiplication, [a; Inv b]))
194 | let multiplier a b = eval (Op (`Multiplication, [a; b]))
195 | let print e = print_endline (texte_depuis_expr e)
196 | end
197 |
198 | module Expr_matrix = Modules.Matrix.Generic_matrix(Expr)
199 |
--------------------------------------------------------------------------------
/src/noyau/moteur.mli:
--------------------------------------------------------------------------------
1 | type context
2 |
3 | val empty_context: context
4 | val texte_depuis_expr : Nouveau_type.expr -> string
5 | val evaluate_with_history: string -> context -> string * context
6 |
7 |
8 |
9 | module Expr :
10 | sig
11 | type t = Nouveau_type.expr
12 | val zero : t
13 | val unit : t
14 | val symb : string -> t
15 | val neg : t -> t
16 | val est_zero : t -> bool
17 | val depuis_texte : string -> t
18 | val vers_texte : t -> string
19 | val additioner : t -> t -> t
20 | val soustraire : t -> t -> t
21 | val diviser : t -> t -> t
22 | val multiplier : t -> t -> t
23 | val print : t -> unit
24 | end
25 |
26 | module Expr_matrix :
27 | sig
28 | type t = Expr.t array array
29 | type solution_equation =
30 | Erreur of string
31 | | Solution_systeme of (string * Expr.t) list
32 | val solveur : string array array -> int -> int -> string array -> solution_equation
33 | end
34 |
--------------------------------------------------------------------------------
/src/noyau/nouveau_lexer.ml:
--------------------------------------------------------------------------------
1 | type operateur =
2 | Plus
3 | | Moins
4 | | Fois
5 | | Division
6 | | Exposant
7 | | Definition
8 |
9 | type token =
10 | Erreur
11 | | EOI
12 | | Blanc
13 | | Digit of string
14 | | Identifiant of string
15 | | Affectation
16 | | Parenthese_ouvrante
17 | | Parenthese_fermante
18 | | Separateur_unite
19 | | Separateur_liste
20 | | Souligne
21 | | Operateur of operateur
22 |
23 | let extraire_blanc s l start =
24 | let aux i =
25 | if i = start then
26 | i, Erreur
27 | else
28 | i, Blanc
29 | in let rec loop i =
30 | if i = l then
31 | aux i
32 | else
33 | match s.[i] with
34 | ('\t' | '\n' | ' ') -> loop (i + 1)
35 | | _ -> aux i
36 | in loop start
37 |
38 | let extraire_digit s l start =
39 | let aux i =
40 | if i = start then
41 | i, Erreur
42 | else
43 | i, Digit (String.sub s start (i - start))
44 | in let rec loop i =
45 | if i = l then
46 | aux i
47 | else
48 | match s.[i] with
49 | '0' .. '9' -> loop (i + 1)
50 | | _ -> aux i
51 | in loop start
52 |
53 | let extraire_identifiant s l start =
54 | let aux i =
55 | if i = start then
56 | i, Erreur
57 | else
58 | i, Identifiant (String.sub s start (i - start))
59 | in let rec loop i =
60 | if i = l then
61 | aux i
62 | else
63 | match s.[i] with
64 | ('a' .. 'z' | 'A' .. 'Z' | '\'' | '_') -> loop (i + 1)
65 | | _ -> aux i
66 | in (* loop start *)
67 | if start = l then
68 | aux start
69 | else
70 | match s.[start] with
71 | ('a' .. 'z' | 'A' .. 'Z') -> loop (start + 1)
72 | | _ -> aux start
73 |
74 | let extraire_jeton_general m lon s l start =
75 | if start + lon <= l then
76 | let rec loop i =
77 | if i - start = lon then
78 | i, true
79 | else if s.[i] = m.[i - start] then
80 | loop (i + 1)
81 | else
82 | i, false
83 | in loop start
84 | else
85 | start, false
86 |
87 | let extraire_parenthese_ouvrante s l start =
88 | match extraire_jeton_general "(" 1 s l start with
89 | | i, true -> i, Parenthese_ouvrante
90 | | _ -> start, Erreur
91 |
92 | let extraire_parenthese_fermante s l start =
93 | match extraire_jeton_general ")" 1 s l start with
94 | | i, true -> i, Parenthese_fermante
95 | | _ -> start, Erreur
96 |
97 | let extraire_separateur_unite s l start =
98 | match extraire_jeton_general "," 1 s l start with
99 | | i, true -> i, Separateur_unite
100 | | _ -> start, Erreur
101 |
102 | let extraire_separateur_liste s l start =
103 | match extraire_jeton_general ";" 1 s l start with
104 | | i, true -> i, Separateur_liste
105 | | _ -> start, Erreur
106 |
107 | let extraire_souligne s l start =
108 | match extraire_jeton_general "_" 1 s l start with
109 | | i, true -> i, Souligne
110 | | _ -> start, Erreur
111 |
112 | let extraire_signe_plus s l start =
113 | match extraire_jeton_general "+" 1 s l start with
114 | | i, true -> i, Operateur Plus
115 | | _ -> start, Erreur
116 |
117 | let extraire_signe_moins s l start =
118 | match extraire_jeton_general "-" 1 s l start with
119 | | i, true -> i, Operateur Moins
120 | | _ -> start, Erreur
121 |
122 | let extraire_signe_fois s l start =
123 | match extraire_jeton_general "*" 1 s l start with
124 | | i, true -> i, Operateur Fois
125 | | _ -> start, Erreur
126 |
127 | let extraire_signe_diviser s l start =
128 | match extraire_jeton_general "/" 1 s l start with
129 | | i, true -> i, Operateur Division
130 | | _ -> start, Erreur
131 |
132 | let extraire_signe_exposant s l start =
133 | match extraire_jeton_general "^" 1 s l start with
134 | | i, true -> i, Operateur Exposant
135 | | _ -> start, Erreur
136 |
137 | let extraire_signe_def s l start =
138 | match extraire_jeton_general ":=" 2 s l start with
139 | | i, true -> i, Operateur Definition
140 | | _ -> start, Erreur
141 |
142 | let iter = [
143 | extraire_blanc;
144 | extraire_digit;
145 | extraire_identifiant;
146 | extraire_parenthese_ouvrante;
147 | extraire_parenthese_fermante;
148 | extraire_separateur_unite;
149 | extraire_separateur_liste;
150 | extraire_souligne;
151 | extraire_signe_plus;
152 | extraire_signe_moins;
153 | extraire_signe_fois;
154 | extraire_signe_diviser;
155 | extraire_signe_exposant;
156 | extraire_signe_def;
157 | ]
158 |
159 | let symbole_suivant s l start =
160 | if l = start then
161 | l, EOI
162 | else
163 | let rec loop = function
164 | f :: reste ->
165 | let i, qqch = f s l start in
166 | if qqch = Erreur then
167 | loop reste
168 | else
169 | i, qqch
170 | | [] -> start, Erreur
171 | in loop iter
172 |
173 | let to_lexbuf s =
174 | let start = 0 in
175 | let l = String.length s in
176 | let rec boucle acc start =
177 | match symbole_suivant s l start with
178 | _, EOI -> List.rev acc
179 | | _, Erreur -> [] (* comment je gère ? *)
180 | | start, qqch -> boucle (qqch :: acc) start
181 | in boucle [] start
182 |
--------------------------------------------------------------------------------
/src/noyau/nouveau_lexer.mli:
--------------------------------------------------------------------------------
1 | type operateur = Plus | Moins | Fois | Division | Exposant | Definition
2 | type token =
3 | Erreur
4 | | EOI
5 | | Blanc
6 | | Digit of string
7 | | Identifiant of string
8 | | Affectation
9 | | Parenthese_ouvrante
10 | | Parenthese_fermante
11 | | Separateur_unite
12 | | Separateur_liste
13 | | Souligne
14 | | Operateur of operateur
15 | val extraire_blanc : string -> int -> int -> int * token
16 | val extraire_digit : string -> int -> int -> int * token
17 | val extraire_identifiant : string -> int -> int -> int * token
18 | val extraire_jeton_general : string -> int -> string -> int -> int -> int * bool
19 | val extraire_parenthese_ouvrante : string -> int -> int -> int * token
20 | val extraire_parenthese_fermante : string -> int -> int -> int * token
21 | val extraire_separateur_unite : string -> int -> int -> int * token
22 | val extraire_separateur_liste : string -> int -> int -> int * token
23 | val extraire_souligne : string -> int -> int -> int * token
24 | val extraire_signe_plus : string -> int -> int -> int * token
25 | val extraire_signe_moins : string -> int -> int -> int * token
26 | val extraire_signe_fois : string -> int -> int -> int * token
27 | val extraire_signe_diviser : string -> int -> int -> int * token
28 | val extraire_signe_exposant : string -> int -> int -> int * token
29 | val extraire_signe_def : string -> int -> int -> int * token
30 | val iter : (string -> int -> int -> int * token) list
31 | val symbole_suivant : string -> int -> int -> int * token
32 | val to_lexbuf : string -> token list
33 |
--------------------------------------------------------------------------------
/src/noyau/nouveau_parser.ml:
--------------------------------------------------------------------------------
1 | type expression =
2 | Vide
3 | | Entier of string
4 | | Reel of string
5 | | Variable of string
6 | | Tuple of int * expression list
7 | | Fonction of string * int * expression list
8 | | Operation of [ `Multiplication | `Addition ] * expression list
9 | | Inverse of expression
10 | | Negation of expression
11 |
12 | type affectable =
13 | Pas_affectable
14 | | Definition_Variable of string
15 | | Definition_fonction of string * int * string list
16 |
17 | type entre_valide =
18 | Erreur of string * Nouveau_lexer.token list
19 | | Expression of expression
20 | | Definition of (affectable * expression) list
21 |
22 | let entier =
23 | let open Nouveau_lexer in
24 | let rec boucle = function
25 | e1, Digit e2 :: l | e1, Blanc :: Digit e2 :: l -> boucle (e1 ^ e2, l)
26 | | e, Souligne :: l -> boucle (e, l)
27 | | e, l -> Entier e, l
28 | in function
29 | (* (Operateur Plus) :: Digit e :: l | *) (* + entier sera traité plus tard *)
30 | Digit e :: l -> boucle (e, l)
31 | | l -> Vide, l
32 |
33 | let reel l =
34 | let open Nouveau_lexer in
35 | let e1, l =
36 | match entier l with
37 | Entier e, l -> Entier e, l
38 | | _ -> Vide, l
39 | in
40 | let virgule, e2, l =
41 | match l with
42 | Separateur_unite :: l -> (
43 | match entier l with
44 | Entier e, l -> true, Entier e, l
45 | | _ -> true, Vide, l
46 | )
47 | | l -> false, Vide, l
48 | in
49 | match e1, e2 with
50 | Entier e1, Entier e2 -> Reel (e1 ^ "," ^ e2), l
51 | | Entier e, Vide -> Entier e, l
52 | | Vide, Entier e -> Reel ("," ^ e), l
53 | | Vide, Vide when virgule -> Reel ",", l
54 | | _, _ -> Vide, l
55 |
56 | let variable =
57 | let open Nouveau_lexer in
58 | function
59 | Identifiant i :: l -> Variable i, l
60 | | l -> Vide, l
61 |
62 | let tuple_de f l =
63 | let open Nouveau_lexer in
64 | let rec boucle n acc = (function
65 | | Parenthese_fermante :: l -> n, List.rev acc, l
66 | | Separateur_liste :: l -> (
67 | match f l with
68 | | Vide, _ -> 1, [Vide], l
69 | | e, l -> boucle (n + 1) (e :: acc) l
70 | )
71 | | l ->
72 | let () = prerr_endline "Parenthese_fermante manquante" in
73 | 1, [Vide], l
74 | )
75 | in match l with
76 | (Parenthese_ouvrante :: l) as original_liste -> (
77 | match f l with
78 | | Vide, _ -> Vide, original_liste
79 | | e, l -> (
80 | match boucle 1 [e] l with
81 | 1, [e], l -> e, l
82 | | n, e, l -> Tuple (n, e), l
83 | )
84 | )
85 | | l -> Vide, l
86 |
87 | let rec fonction l =
88 | let open Nouveau_lexer in
89 | match l with
90 | (Identifiant f :: l) as original_liste -> (
91 | match tuple_de expression l with
92 | | Tuple (n, liste_de_parametres), l -> Fonction (f, n, liste_de_parametres), l
93 | | x, l when x <> Vide -> Fonction (f, 1, [x]), l
94 | | _, _ -> Vide, original_liste (* c'est forcement Vide *)
95 | )
96 | | l -> Vide, l
97 |
98 | and facteur l =
99 | match reel l with
100 | Vide, _ -> (
101 | match entier l with
102 | Vide, _ -> (
103 | match fonction l with
104 | Vide, _ -> (
105 | match variable l with
106 | Vide, _ -> tuple_de expression l
107 | | e, l -> e, l
108 | )
109 | | e, l -> e, l
110 | )
111 | | e, l -> e, l
112 | )
113 | | e, l -> e, l
114 |
115 | and terme l =
116 | let open Nouveau_lexer in
117 | let rec boucle acc = function
118 | (Operateur Fois | Blanc) :: l -> (
119 | match facteur l with
120 | Vide, _ -> [Vide], l
121 | (*| (Entier _ | Reel _) as e, Identifiant i :: l -> boucle (Variable i :: e :: acc) l*)
122 | | e, l -> boucle (e :: acc) l
123 | )
124 | | Operateur Division :: l -> (
125 | match facteur l with
126 | Vide, _ -> [Vide], l
127 | | e, l -> boucle (Inverse e :: acc) l
128 | )
129 | | l -> List.rev acc, l
130 | in let inverse, l =
131 | match l with
132 | Operateur Division :: l -> true, l
133 | | Operateur Fois :: l | l -> false, l
134 | in match facteur l with
135 | Vide, _ -> Vide, l (* todo error handling*)
136 | | e, l ->
137 | match boucle [if inverse then Inverse e else e] l with
138 | [e], l -> e, l
139 | | e, l -> Operation (`Multiplication, e), l
140 |
141 | and expression l =
142 | let open Nouveau_lexer in
143 | let rec boucle acc l =
144 | match l with
145 | Operateur Plus :: l -> (
146 | match terme l with
147 | Vide, _ -> [Vide], l
148 | | e, l -> boucle (e :: acc) l
149 | )
150 | | Operateur Moins :: l -> (
151 | match terme l with
152 | Vide, _ -> [Vide], l
153 | | e, l -> boucle (Negation e :: acc) l
154 | )
155 | | l -> List.rev acc, l
156 | in let negatif, l =
157 | match l with
158 | Operateur Moins :: l -> true, l
159 | | Operateur Plus :: l | l -> false, l
160 | in match terme l with
161 | Vide, _ -> Vide, l (* todo error handling*)
162 | | e, l ->
163 | match boucle [if negatif then Negation e else e] l with
164 | [e], l -> e, l
165 | | e, l -> Operation (`Addition, e), l
166 |
167 | let est_affectable e =
168 | match e with
169 | Variable _ -> true
170 | | Fonction (_, _, l) -> List.for_all (fun e -> match e with Variable _ -> true | _ -> false) l
171 | | _ -> false
172 |
173 | let tous_affectable e =
174 | match e with
175 | Tuple (_, l) -> List.for_all est_affectable l
176 | | e -> est_affectable e
177 |
178 | let exrp_l_to_string_l l = List.map (fun e -> match e with Variable x -> x | _ -> "error") l
179 |
180 | let expr_to_def = function
181 | Variable x, e -> Definition_Variable x, e
182 | | Fonction (name, n, l), e -> Definition_fonction (name, n, exrp_l_to_string_l l), e
183 | | _, _ -> Pas_affectable, Vide
184 |
185 | let exprs_to_def = function
186 | Variable x, e -> Definition [Definition_Variable x, e]
187 | | Fonction (name, n, l), e -> Definition [Definition_fonction (name, n, exrp_l_to_string_l l), e]
188 | | Tuple(a, la), Tuple(b, lb) ->
189 | if a = b then
190 | Definition (List.map2 (fun a b -> expr_to_def (a, b)) la lb)
191 | else
192 | Erreur ("nombre de membre incorrect", [])
193 | | _, _ -> Erreur ("WTF", [])
194 |
195 | let expression_principale l =
196 | match expression l with
197 | e, Nouveau_lexer.Operateur Nouveau_lexer.Definition :: l -> (
198 | if tous_affectable e then
199 | match expression l with
200 | Vide, _ -> Erreur ("membre droit incorrect", [])
201 | | e2, [] -> exprs_to_def (e, e2)
202 | | _, l -> Erreur ("caracteres restant", l)
203 | else
204 | Erreur ("membre de gauche non assignable", [])
205 | )
206 | | Vide, l -> Erreur (I18n.erreur_de_syntaxe (), l)
207 | | e, [] -> Expression e
208 | | _, l -> Erreur ("caracteres restant", l)
209 |
210 |
211 | let filtre =
212 | let open Nouveau_lexer in
213 | let rec filtre acc =
214 | function
215 | Blanc :: [] | [] -> List.rev acc
216 | | Blanc :: (Operateur v) :: l | (Operateur v) :: Blanc :: l -> filtre acc ((Operateur v) :: l)
217 | | Blanc :: Separateur_liste :: l | Separateur_liste :: Blanc :: l -> filtre acc (Separateur_liste :: l)
218 | | Parenthese_ouvrante :: Blanc :: l -> filtre acc (Parenthese_ouvrante :: l)
219 | | Blanc :: Parenthese_fermante :: l -> filtre acc (Parenthese_fermante :: l)
220 | | Blanc :: Separateur_unite :: l -> filtre acc (Separateur_unite :: l)
221 | | Separateur_unite :: Blanc :: Digit e :: l -> filtre acc (Separateur_unite :: Digit e :: l)
222 | | e :: l -> filtre (e :: acc) l
223 | in function
224 | Blanc :: l -> filtre [] l
225 | | l -> filtre [] l
226 |
227 | let parse s =
228 | let lexbuf = Nouveau_lexer.to_lexbuf s in
229 | let lexbuf = filtre lexbuf in
230 | expression_principale lexbuf
231 |
--------------------------------------------------------------------------------
/src/noyau/nouveau_parser.mli:
--------------------------------------------------------------------------------
1 | type expression =
2 | Vide
3 | | Entier of string
4 | | Reel of string
5 | | Variable of string
6 | | Tuple of int * expression list
7 | | Fonction of string * int * expression list
8 | | Operation of [ `Addition | `Multiplication ] * expression list
9 | | Inverse of expression
10 | | Negation of expression
11 | type affectable =
12 | Pas_affectable
13 | | Definition_Variable of string
14 | | Definition_fonction of string * int * string list
15 | type entre_valide =
16 | Erreur of string * Nouveau_lexer.token list
17 | | Expression of expression
18 | | Definition of (affectable * expression) list
19 | val entier :
20 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list
21 | val reel :
22 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list
23 | val variable :
24 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list
25 | val tuple_de :
26 | (Nouveau_lexer.token list -> expression * Nouveau_lexer.token list) ->
27 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list
28 | val fonction :
29 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list
30 | val facteur :
31 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list
32 | val terme :
33 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list
34 | val expression :
35 | Nouveau_lexer.token list -> expression * Nouveau_lexer.token list
36 | val est_affectable : expression -> bool
37 | val tous_affectable : expression -> bool
38 | val exrp_l_to_string_l : expression list -> string list
39 | val expr_to_def : expression * expression -> affectable * expression
40 | val exprs_to_def : expression * expression -> entre_valide
41 | val expression_principale : Nouveau_lexer.token list -> entre_valide
42 | val filtre : Nouveau_lexer.token list -> Nouveau_lexer.token list
43 | val parse : string -> entre_valide
44 |
--------------------------------------------------------------------------------
/src/noyau/nouveau_type.ml:
--------------------------------------------------------------------------------
1 | open Lien
2 |
3 | type constantes =
4 | Pi
5 | (* Quaternion constantes*)
6 | | I
7 | | J
8 | | K
9 |
10 | type expr =
11 | N of GrandNum.num
12 | | C of constantes
13 | | Var of string
14 | | T of int * expr list
15 | | Fx of string * int * expr list
16 | | Op of [ `Multiplication | `Addition ] * expr list
17 | | Inv of expr
18 | | Neg of expr
19 |
20 | type affe =
21 | Def_Var of string
22 | | Def_Fx of string * int * string list
23 |
24 | let rec expr_depuis_expression =
25 | let open Nouveau_parser in
26 | function
27 | Vide -> failwith (I18n.impossible_convertir_vide ())
28 | | Entier s -> N (GrandNum.E (GrandEntier.grandentier_depuis_texte s))
29 | | Reel s -> N (GrandNum.R (GrandReel.grandreel_depuis_texte s))
30 | | Variable ("pi" | "pI" | "Pi" | "PI") -> C Pi
31 | | Variable ("i" | "I") -> C I
32 | | Variable ("j" | "J") -> C J
33 | | Variable ("k" | "K") -> C K
34 | | Variable s -> Var s
35 | | Tuple (n, l) -> T (n, List.map expr_depuis_expression l)
36 | | Fonction (s, n, l) -> Fx (s, n, List.map expr_depuis_expression l)
37 | | Operation (a, l) -> Op (a, List.map expr_depuis_expression l)
38 | | Inverse e -> Inv (expr_depuis_expression e)
39 | | Negation e -> Neg (expr_depuis_expression e)
40 |
41 | let affe_depuis_affectable =
42 | let open Nouveau_parser in
43 | function
44 | Pas_affectable -> failwith (I18n.impossible_convertir_pas_affectable ())
45 | | Definition_Variable s -> Def_Var s
46 | | Definition_fonction (f, n, l) -> Def_Fx (f, n, l)
47 |
--------------------------------------------------------------------------------
/src/noyau/parser.ml:
--------------------------------------------------------------------------------
1 | open Lien
2 | open Type
3 | open Utils
4 | open Lexer
5 |
6 | (** only for test purpose *)
7 | let ge t = (Obj.magic (GrandEntier.grandentier_depuis_texte t) : Lien.GrandEntier.grandentier)
8 | (** only for test purpose *)
9 |
10 | let variable_de_entier _ t(*exte*) = Entier (GrandEntier.grandentier_depuis_texte t)
11 |
12 | let variable_de_texte _ t(*texte*) = Variable t
13 |
14 | let neg = function
15 | Entier e -> Entier (GrandEntier.neg e)
16 | | a -> Neg a
17 |
18 | let variable_de_addition_soustraction compile t(*texte*) =
19 | let l = couper_texte t ['+'; '-'] in
20 | let premier_el = function
21 | [] | [_] | [_; _] -> failwith "chut OCaml"
22 | | "" :: "-" :: e :: liste -> [neg (compile e)], liste
23 | | "" :: "+" :: e :: liste -> [compile e], liste
24 | | e :: liste -> [compile e], liste
25 | in
26 | let (premier, l) = premier_el l in
27 | let rec boucle acc = function
28 | [_] -> failwith "chut OCaml"
29 | | [] -> List.rev acc
30 | | "+" :: e :: liste -> boucle (compile e :: acc) liste
31 | | "-" :: e :: liste -> boucle (neg (compile e) :: acc) liste
32 | |_-> failwith "error"
33 |
34 | in match boucle premier l with
35 | [] -> failwith "chut OCaml"
36 | | [e] -> e (* l'addition d'un terme est le terme lui même *)
37 | | l -> Operation ("+", l)
38 |
39 | let variable_de_multiplication_division compile t(*texte*) =
40 | let l = couper_texte t ['*'; '/'] in
41 | let premier_el = function
42 | [] | [_] | [_; _] -> failwith "chut OCaml"
43 | | "" :: "/" :: e :: liste -> [Entier (GrandEntier.unit)], "/" :: e :: liste
44 | | "" :: "*" :: e :: liste -> [Entier (GrandEntier.unit)], "*" :: e :: liste
45 | | e :: liste -> [compile e], liste
46 | in
47 | let (premier, l) = premier_el l in
48 | let rec boucle acc = function
49 | [_] -> failwith "chut OCaml"
50 | | [] -> List.rev acc
51 | | "*" :: e :: liste -> boucle (compile e :: acc) liste
52 | | "/" :: e :: liste -> boucle (Inv (compile e) :: acc) liste
53 | |_-> failwith "error"
54 |
55 | in match boucle premier l with
56 | [] -> failwith "chut OCaml"
57 | | [e] -> e (* l'addition d'un terme est le terme lui même *)
58 | | l -> Operation ("*", l)
59 |
60 | let parse =
61 | let parse = [] in
62 | let parse = (est_multiplication_division, variable_de_multiplication_division) :: parse in
63 | let parse = (est_addition_soustraction, variable_de_addition_soustraction) :: parse in
64 | let parse = (est_variable, variable_de_texte) :: parse in
65 | let parse = (est_entier10, variable_de_entier) :: parse in
66 | parse
67 |
68 | let rec expr_de_texte_etend fxs(*list of function*) t(*exte*) =
69 | let f = expr_de_texte_etend fxs in
70 | let rec b(*oucle*) = function
71 | (p(*redicat*), c(*onvertisseur*)) :: _ when p t -> c f t
72 | | _ :: l -> b l
73 | | [] -> Textenonvalide t
74 | in b fxs
75 |
76 | let expr_de_texte = expr_de_texte_etend parse
77 |
78 | let rec texte_de_expr ?paren = function
79 | Variable nom -> nom
80 | | Entier ga -> GrandEntier.texte_depuis_grandentier ga
81 | | Neg e -> "(-" ^ texte_de_expr e ^ ")"
82 | | Inv e -> "(1/" ^ texte_de_expr e ^ ")"
83 | | Textenonvalide s -> s
84 | | Operation (_, []) -> failwith "On a une operation sans operande"
85 | | Operation (_, e :: []) -> texte_de_expr e
86 | | Operation (op, e :: l) ->
87 | let s =
88 | texte_de_expr e ^ op ^ (texte_de_expr ?paren:(Some false) (Operation (op, l))) in
89 | match paren with
90 | None | Some true -> "(" ^ s ^ ")"
91 | | Some false -> s
92 |
--------------------------------------------------------------------------------
/src/noyau/parser.mli:
--------------------------------------------------------------------------------
1 | val ge: string -> Lien.GrandEntier.grandentier
2 |
3 | val variable_de_entier : (string -> Type.expr) -> string -> Type.expr
4 |
5 | val variable_de_texte : (string -> Type.expr) -> string -> Type.expr
6 |
7 | val variable_de_addition_soustraction : (string -> Type.expr) -> string -> Type.expr
8 |
9 | val variable_de_multiplication_division : (string -> Type.expr) -> string -> Type.expr
10 |
11 | val texte_de_expr : ?paren: bool -> Type.expr -> string
12 |
13 | val expr_de_texte_etend : ((string -> bool) * ((string -> Type.expr) -> string -> Type.expr)) list -> string -> Type.expr
14 |
15 | val expr_de_texte : string -> Type.expr
16 |
--------------------------------------------------------------------------------
/src/noyau/type.ml:
--------------------------------------------------------------------------------
1 | open Lien
2 |
3 | type expr = Variable of string
4 | | Entier of GrandEntier.grandentier
5 | | Textenonvalide of string
6 | | Operation of string * expr list
7 | | Neg of expr
8 | | Inv of expr
9 |
--------------------------------------------------------------------------------
/src/noyau/type.mli:
--------------------------------------------------------------------------------
1 | type expr =
2 | Variable of string
3 | | Entier of Lien.GrandEntier.grandentier
4 | | Textenonvalide of string
5 | | Operation of string * expr list
6 | | Neg of expr
7 | | Inv of expr
8 |
--------------------------------------------------------------------------------
/src/noyau/utils.ml:
--------------------------------------------------------------------------------
1 | let print_bool b =
2 | print_endline (
3 | if b then
4 | "true"
5 | else
6 | "false"
7 | )
8 |
9 | let contient_texte t(*exte*) l(*iste à chercher*) =
10 | let car_dans_liste c =
11 | let rec boucle = function
12 | []-> false
13 | | e :: l -> c = e || boucle l
14 | in boucle l
15 | in let len = String.length t in
16 | let rec boucle p(*arenthèses*) c(*rochets*) a(*ccolades*) i =
17 | if i < len then
18 | match t.[i] with
19 | '(' -> boucle (p + 1) c a (i + 1)
20 | | '[' -> boucle p (c + 1) a (i + 1)
21 | | '{' -> boucle p c (a + 1) (i + 1)
22 | | ')' -> boucle (p - 1) c a (i + 1)
23 | | ']' -> boucle p (c - 1) a (i + 1)
24 | | '}' -> boucle p c (a - 1) (i + 1)
25 | | lettre -> p = 0 && c = 0 && a = 0 && car_dans_liste lettre || boucle p c a (i + 1)
26 | else
27 | false
28 | in boucle 0 0 0 0
29 |
30 | let couper_texte t(*exte*) l(*iste à chercher*) =
31 | let car_dans_liste c =
32 | let rec boucle = function
33 | []-> false
34 | | e :: l -> c = e || boucle l
35 | in boucle l
36 | in let len = String.length t in
37 | let start = ref 0 in
38 | let rec boucle p(*arenthèses*) c(*rochets*) a(*ccolades*) i acc =
39 | if i < len then
40 | match t.[i] with
41 | '(' -> boucle (p + 1) c a (i + 1) acc
42 | | '[' -> boucle p (c + 1) a (i + 1) acc
43 | | '{' -> boucle p c (a + 1) (i + 1) acc
44 | | ')' -> boucle (p - 1) c a (i + 1) acc
45 | | ']' -> boucle p (c - 1) a (i + 1) acc
46 | | '}' -> boucle p c (a - 1) (i + 1) acc
47 | | lettre -> if p = 0 && c = 0 && a = 0 && car_dans_liste lettre then
48 | let acc = String.sub t i 1 :: String.sub t !start (i - !start) :: acc in
49 | let () = start := i + 1 in
50 | boucle p c a (i + 1) acc
51 | else
52 | boucle p c a (i + 1) acc
53 | else
54 | let acc = String.sub t !start (i - !start) :: acc in
55 | List.rev acc
56 | in boucle 0 0 0 0 []
57 |
58 | let parenthese_correcte t(*exte*)=
59 | let len = String.length t in
60 | let rec boucle i acc =
61 | if i < len then
62 | match t.[i], acc with
63 | ('(' as o), _ | ('[' as o), _ | ('{' as o), _ -> boucle (i + 1) (o :: acc)
64 | | ')', '(' :: acc -> boucle (i + 1) acc
65 | | ']', '[' :: acc -> boucle (i + 1) acc
66 | | '}', '{' :: acc -> boucle (i + 1) acc
67 | | ')', _ :: _ | ']', _ :: _ | '}', _ :: _ | ')', [] | ']', [] | '}', [] -> false
68 | | _ -> boucle (i + 1) acc
69 | else
70 | acc = []
71 | in boucle 0 []
72 |
--------------------------------------------------------------------------------
/src/noyau/utils.mli:
--------------------------------------------------------------------------------
1 | val print_bool : bool -> unit
2 | val contient_texte : string -> char list -> bool
3 | val couper_texte : string -> char list -> string list
4 | val parenthese_correcte : string -> bool
5 |
--------------------------------------------------------------------------------