why z3 solver give bool variable "none", how to get rid of it? - z3
I am new to Z3py. I am trying to list all satisfied solutions to a bool formula (or to get the truth table which generate only True).
My code is here, inspired from another answer finding all satisfying models:
from z3 import *
A1, B1, B2, C1, C2, E1, E2, F4 = Bools('A1 B1 B2 C1 C2 E1 E2 F4')
s = Solver()
s.add(simplify(Or(And(A1, Or(C1, C2), Or(B1, B2), E2, F4),
And(A1, C2, Or(B1, B2), E1))))
while s.check() == sat:
print(s.model())
s.add(Or(A1 != s.model()[A1],
B1 != s.model()[B1],
B2 != s.model()[B2],
C1 != s.model()[C1],
C2 != s.model()[C2],
E1 != s.model()[E1],
E2 != s.model()[E2],
F4 != s.model()[F4]))
but I got results like this:
True,True,None,None,True,True,False,None
True,True,None,None,True,True,False,None
True,True,None,None,True,True,False,None
True,True,None,None,True,True,False,None
...
as you can see, they have duplicated results, and there are "None" in it, why is this happening? Isn't it true that Bool variable has only "true" or "false"? Why there are duplicated models in it? Thank you very much.
None is a don't-care; it means that you are free to choose either True or False and both are valid models. You can ask Z3 to fill in these values by enabling model completion, for example as it's done in How to model in Z3py
As Cristoph mentioned, if you are interested in complete enumeration, you want to make sure the "don't-care" assignments are always fixed at a particular value. To address the issue, you can use the following code:
from z3 import *
A1, B1, B2, C1, C2, E1, E2, F4 = Bools('A1 B1 B2 C1 C2 E1 E2 F4')
s = Solver()
s.add(simplify(Or(And(A1, Or(C1, C2), Or(B1, B2), E2, F4),.
And(A1, C2, Or(B1, B2), E1))))
vars = [A1, B1, B2, C1, C2, E1, E2, F4]
while s.check() == sat:
m = s.model()
for v in vars:
print("%s = %5s" % (v, m.evaluate(v, model_completion = True))),
print
s.add(Or([p != v for p, v in [(v, m.evaluate(v, model_completion = True)) for v in vars]]))
When run, this prints:
A1 = True B1 = True B2 = False C1 = False C2 = True E1 = True E2 = True F4 = True
A1 = True B1 = True B2 = False C1 = False C2 = True E1 = True E2 = False F4 = False
A1 = True B1 = True B2 = True C1 = False C2 = True E1 = True E2 = False F4 = False
A1 = True B1 = False B2 = True C1 = True C2 = True E1 = True E2 = False F4 = False
A1 = True B1 = True B2 = True C1 = True C2 = True E1 = True E2 = False F4 = False
A1 = True B1 = True B2 = True C1 = True C2 = True E1 = True E2 = True F4 = False
A1 = True B1 = False B2 = True C1 = False C2 = True E1 = True E2 = True F4 = False
A1 = True B1 = False B2 = True C1 = True C2 = True E1 = True E2 = True F4 = False
A1 = True B1 = False B2 = True C1 = True C2 = False E1 = False E2 = True F4 = True
A1 = True B1 = True B2 = False C1 = True C2 = False E1 = False E2 = True F4 = True
A1 = True B1 = True B2 = False C1 = True C2 = True E1 = False E2 = True F4 = True
A1 = True B1 = True B2 = False C1 = True C2 = True E1 = True E2 = False F4 = True
A1 = True B1 = True B2 = False C1 = True C2 = True E1 = True E2 = True F4 = False
A1 = True B1 = True B2 = False C1 = True C2 = True E1 = True E2 = True F4 = True
A1 = True B1 = True B2 = False C1 = False C2 = True E1 = True E2 = False F4 = True
A1 = True B1 = True B2 = True C1 = False C2 = True E1 = True E2 = False F4 = True
A1 = True B1 = True B2 = True C1 = True C2 = True E1 = True E2 = False F4 = True
A1 = True B1 = False B2 = True C1 = True C2 = True E1 = True E2 = False F4 = True
A1 = True B1 = False B2 = True C1 = True C2 = False E1 = True E2 = True F4 = True
A1 = True B1 = True B2 = False C1 = True C2 = False E1 = True E2 = True F4 = True
A1 = True B1 = True B2 = True C1 = True C2 = False E1 = False E2 = True F4 = True
A1 = True B1 = True B2 = True C1 = True C2 = False E1 = True E2 = True F4 = True
A1 = True B1 = True B2 = False C1 = False C2 = True E1 = False E2 = True F4 = True
A1 = True B1 = False B2 = True C1 = False C2 = True E1 = False E2 = True F4 = True
A1 = True B1 = False B2 = True C1 = False C2 = True E1 = True E2 = False F4 = False
A1 = True B1 = True B2 = False C1 = True C2 = True E1 = True E2 = False F4 = False
A1 = True B1 = False B2 = True C1 = True C2 = True E1 = False E2 = True F4 = True
A1 = True B1 = True B2 = True C1 = False C2 = True E1 = False E2 = True F4 = True
A1 = True B1 = True B2 = True C1 = True C2 = True E1 = False E2 = True F4 = True
A1 = True B1 = True B2 = True C1 = False C2 = True E1 = True E2 = True F4 = False
A1 = True B1 = True B2 = False C1 = False C2 = True E1 = True E2 = True F4 = False
A1 = True B1 = False B2 = True C1 = False C2 = True E1 = True E2 = True F4 = True
A1 = True B1 = False B2 = True C1 = True C2 = True E1 = True E2 = True F4 = True
A1 = True B1 = True B2 = True C1 = True C2 = True E1 = True E2 = True F4 = True
A1 = True B1 = True B2 = True C1 = False C2 = True E1 = True E2 = True F4 = True
A1 = True B1 = False B2 = True C1 = False C2 = True E1 = True E2 = False F4 = True
Which doesn't have any Nones or duplications.
Related
Convert an array to matrix to find adjacent elements iOS swift
Convert this below array into matrix Array let ptsArray = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] Matrix 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 To find adjacent points in uniderectional like an below image Expected output (0,1) (0,6) (1,2) (1,7) (2,3) (2,8) (3,4) (3,9) (4,5) (4,10) (5,11) (6,7) (6,12) (7,8) (7,13) (8,9) (8,14) (9,10) (9,15) (10,11) (10,16) (11,17) (12,13) (13,14) (14,15) (15,16) (16,17) My failed approach for i in 0..<pointsArray.count-1{ if (i+1)%6 == 0 && i != 0{ print("Connection (\(i),\(i+6))") nodesArray[i].addConnection(to: nodesArray[i+6], bidirectional: true, weight: 1) } if i>=pointsArray.count-6{ print("Connection (\(i),\(i+1))") nodesArray[i].addConnection(to: nodesArray[i+1], bidirectional: true, weight: 1) } else{ print("Connection (\(i),\(i+1)) (\(i),\(i+6))") nodesArray[i].addConnection(to: nodesArray[i+1], bidirectional: true, weight: 1) nodesArray[i].addConnection(to: nodesArray[i+6], bidirectional: true, weight: 1) } } Output: Connection (0,1) (0,6) Connection (1,2) (1,7) Connection (2,3) (2,8) Connection (3,4) (3,9) Connection (4,5) (4,10) Connection (5,11) Connection (5,6) (5,11) Connection (6,7) (6,12) Connection (7,8) (7,13) Connection (8,9) (8,14) Connection (9,10) (9,15) Connection (10,11) (10,16) Connection (11,17) Connection (11,12) (11,17) Connection (12,13) Connection (13,14) Connection (14,15) Connection (15,16) Connection (16,17)
In the desired output, I guess that it's missing (9,15), (10,11), (10,16) and that (10,15) isn't valid. If we think about your desired output, we notice something. Let's name width = 6, it's the "width" of your matrix. We see the pattern: (value, value + 1), (value, value + width) With some excluded tests: does (value + width) exists ? And we are not at the end of the width. Let's, with a little reduce method: let ptsArray = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] let width = 6 let tuples = ptsArray.indices.reduce(into: [(Int, Int)]()) { partialResult, anIndex in if ptsArray.count > anIndex.advanced(by: 1) && anIndex % width != width - 1 { let newValue = (ptsArray[anIndex], ptsArray[anIndex.advanced(by: 1)]) print(newValue) partialResult.append(newValue) } if ptsArray.count > anIndex.advanced(by: width) { let newValue = (ptsArray[anIndex], ptsArray[anIndex.advanced(by: width)]) print(newValue) partialResult.append(newValue) } return } print(tuples) I used "index", because in fact, points are in order here, but it could be any value, no? So let's use the index instead. So, with something a little more generic: extension Array { func coupling(with width: Int) -> [(Element, Element)] { let couples = indices.reduce(into: [(Element, Element)]()) { partialResult, anIndex in if count > anIndex.advanced(by: 1) && anIndex % width != width - 1 { let newValue = (self[anIndex], self[anIndex.advanced(by: 1)]) partialResult.append(newValue) } if count > anIndex.advanced(by: width) { let newValue = (self[anIndex], self[anIndex.advanced(by: width)]) partialResult.append(newValue) } return } return couples } } Use: let ptsArray = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] let tuples2 = ptsArray. coupling(with: width) print(tuples2) let lettersArray = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P", "Q", "R"] let tuples3 = lettersArray. coupling(with: width) print(tuples3)
Another approach - convert your ptsArray into a 2-D matrix: var matrix: [[Int]] = [] let numCols: Int = 6 var numRows: Int = 0 let ptsArray: [Int] = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] for i in stride(from: 0, to: ptsArray.count, by: numCols) { // make sure we don't exceed the array limit if ptsArray.count >= i+numCols { matrix.append(Array(ptsArray[i..<i+numCols])) } } numRows = matrix.count You can now get the right and down values (if they exist) like this: func getPair2D(_ n: Int) -> (Int?, Int?) { let thisRow = n / numCols let thisCol = n % numCols let numToRight = thisCol < numCols-1 ? matrix[thisRow][thisCol+1] : nil let numToDown = thisRow < numRows-1 ? matrix[thisRow+1][thisCol] : nil return (numToRight, numToDown) } and this will print out the results: for i in 0..<ptsArray.count { let (n1, n2) = getPair2D(i) var str = "" if let n1 = n1 { str += "(\(i), \(n1))" } if let n2 = n2 { if !str.isEmpty { str += " " } str += "(\(i), \(n2))" } print(str) } Here's a simple view controller that let's you tap any number to show the "right and down" matches: class MatrixVC: UIViewController { var matrix: [[Int]] = [] var views: [UIView] = [] let numCols: Int = 6 var numRows: Int = 0 override func viewDidLoad() { super.viewDidLoad() let ptsArray: [Int] = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] for i in stride(from: 0, to: ptsArray.count, by: numCols) { if ptsArray.count >= i+numCols { matrix.append(Array(ptsArray[i..<i+numCols])) } } numRows = matrix.count let oStack: UIStackView = { let v = UIStackView() v.axis = .vertical v.distribution = .fillEqually v.spacing = 2 return v }() var n = 0 for r in 0..<numRows { let rStack: UIStackView = { let v = UIStackView() v.axis = .horizontal v.distribution = .fillEqually v.spacing = 2 return v }() for c in 0..<numCols { let v = UILabel() v.textAlignment = .center v.text = "\(ptsArray[n])" v.isUserInteractionEnabled = true let t = UITapGestureRecognizer(target: self, action: #selector(gotTap(_:))) v.addGestureRecognizer(t) rStack.addArrangedSubview(v) views.append(v) if c < numCols-1 { let iv = UIImageView(image: UIImage(systemName: "arrow.right")) rStack.addArrangedSubview(iv) } n += 1 } oStack.addArrangedSubview(rStack) if r < numRows-1 { let rStack: UIStackView = { let v = UIStackView() v.axis = .horizontal v.distribution = .fillEqually v.spacing = 2 return v }() for c in 0..<numCols { let iv = UIImageView(image: UIImage(systemName: "arrow.down")) rStack.addArrangedSubview(iv) if c < numCols-1 { let v = UIView() rStack.addArrangedSubview(v) } } oStack.addArrangedSubview(rStack) } } oStack.translatesAutoresizingMaskIntoConstraints = false view.addSubview(oStack) let g = view.safeAreaLayoutGuide NSLayoutConstraint.activate([ oStack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0), oStack.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -40.0), oStack.centerXAnchor.constraint(equalTo: g.centerXAnchor), oStack.centerYAnchor.constraint(equalTo: g.centerYAnchor), ]) } #objc func gotTap(_ g: UITapGestureRecognizer) { guard let v = g.view as? UILabel, let t = v.text, let n = Int(t) else { return } // if the tapped label is yellow, let's just deselect all let deselecting: Bool = views[n].backgroundColor == .yellow views.forEach { $0.backgroundColor = .clear } if deselecting { return() } views[n].backgroundColor = .yellow let (n1, n2) = getPair2D(n) if let n1 = n1 { views[n1].backgroundColor = .yellow } if let n2 = n2 { views[n2].backgroundColor = .yellow } } func getPair2D(_ n: Int) -> (Int?, Int?) { let thisRow = n / numCols let thisCol = n % numCols let numToRight = thisCol < numCols-1 ? matrix[thisRow][thisCol+1] : nil let numToDown = thisRow < numRows-1 ? matrix[thisRow+1][thisCol] : nil return (numToRight, numToDown) } } It looks like this: Tapping any number will highlight the pair: Tapping a "highlighted" number will "un-highlight" all numbers.
Calculating total price present in shopping cart
is how my shopping cart looks like.. I am trying to calculate the subtotal price based on the products present in the cart dynamically. My code is here : func displaySubTotal() { if cartArray.count == 1 { let p1 = Double(cartArray[0].cartItems.price) let p2 = Double(cartArray[0].cartQuantity) let p = Double(p1! * p2) let x1 = Double(p) subtotalPrice.text = "\(x1)" } if cartArray.count == 2 { let p1 = Double(cartArray[0].cartItems.price) let p2 = Double(cartArray[0].cartQuantity) let p = Double(p1! * p2) let q1 = Double(cartArray[1].cartItems.price) let q2 = Double(cartArray[1].cartQuantity) let q = Double(q1! * q2) let x2 = Double(p + q) subtotalPrice.text = "\(x2)" } if cartArray.count == 3 { let p1 = Double(cartArray[0].cartItems.price) let p2 = Double(cartArray[0].cartQuantity) let p = Double(p1! * p2) let q1 = Double(cartArray[1].cartItems.price) let q2 = Double(cartArray[1].cartQuantity) let q = Double(q1! * q2) let r1 = Double(cartArray[2].cartItems.price) let r2 = Double(cartArray[2].cartQuantity) let r = Double(r1! * r2) let x3 = Double(p + q + r) subtotalPrice.text = "\(x3)" } if cartArray.count == 4 { let p1 = Double(cartArray[0].cartItems.price) let p2 = Double(cartArray[0].cartQuantity) let p = Double(p1! * p2) let q1 = Double(cartArray[1].cartItems.price) let q2 = Double(cartArray[1].cartQuantity) let q = Double(q1! * q2) let r1 = Double(cartArray[2].cartItems.price) let r2 = Double(cartArray[2].cartQuantity) let r = Double(r1! * r2) let s1 = Double(cartArray[3].cartItems.price)! let s2 = Double(cartArray[3].cartQuantity) let s = Double(s1 * s2) let x4 = Double(p + q + r + s) subtotalPrice.text = "\(x4)" } if cartArray.count == 5 { let p1 = Double(cartArray[0].cartItems.price) let p2 = Double(cartArray[0].cartQuantity) let p = Double(p1! * p2) let q1 = Double(cartArray[1].cartItems.price) let q2 = Double(cartArray[1].cartQuantity) let q = Double(q1! * q2) let r1 = Double(cartArray[2].cartItems.price) let r2 = Double(cartArray[2].cartQuantity) let r = Double(r1! * r2) let s1 = Double(cartArray[3].cartItems.price)! let s2 = Double(cartArray[3].cartQuantity) let s = Double(s1 * s2) let t1 = Double(cartArray[4].cartItems.price)! let t2 = Double(cartArray[4].cartQuantity) let t = Double(t1 * t2) let x5 = Double(p + q + r + s + t) subtotalPrice.text = "\(x5)" } } But I can't make it dynamic (price is needed to be updated with the delete of products instantly & addition/subtraction of quantity [using the (+ & -) buttons] of products). I'm trying this kind of thing for the first time. Please suggest me hoe to solve this! Thanks in advance..
Just loop over your cart items. (item_price * quantity) func displaySubTotal() { var total_price: Float = 0.0 for items in cartArray { if let price = Float(items.cartItems.price) { total_price += Float(items.cartQuantity) * price } } subtotalPrice.text = "\(total_price)" } #objc func add(sender: UIButton) { if cartArray[sender.tag].cartQuantity >= 0 { cartArray[sender.tag].cartQuantity += 1 cartTableView.reloadData() self.displaySubTotal() } } #objc func sub(sender: UIButton) { if cartArray[sender.tag].cartQuantity > 0 { cartArray[sender.tag].cartQuantity -= 1 cartTableView.reloadData() self.displaySubTotal() } }
elegant way to call async functions in a match statement, in F#
This cannot work: let a () = async { return 0 } let b x = async { return match x with | true -> let! y = a() <- you can't compile this y | false -> 0 } I understand I could do this: let b x = async { match x with | true -> return! a() | false -> return 0 } but there are cases where I need a: let! y = a() to do more operations with the result. Is there an elegant way to achieve this?
Can't you combine the two? let b x = async { match x with | true -> let! y = a() return y | false -> return 0 }
You can move the async expression inside each case: let b x = match x with | true -> async { let! y = a () ... return y } | false -> async { return 0 }
I don't know if you think this is more elegant, but more functions usually makes it look a bit nicer, here's an example: module Async = let create v = async { return v } let bind f a = async.Bind (a, f) let map f a = bind (f >> create) a let a () = Async.create 0 let addOne y = y + 1 let b x = match x with | true -> a () |> Async.map addOne | false -> Async.create 0 // Additional piping to map or bind if you wish, e.g: // |> Async.bind ...
You can do the return inside the match. let a () = async { return 0 } let b x = async { match x with | true -> return! a() | false -> return 0 } Otherwise you can do this: module Async = let create x = async { return x } let a () = async { return 10 } let b x = async { let! x1 = match x with | true -> a() | false -> async { return 0 } let! x2 = if x then a() else Async.create 0 // Do whatever with x1 or x2 return x2 } Create a function for code that occur often: let whatever b a x = if x then a() else Async.create x let! y = whatever b a 0
Swift Chart months at bottom
I'm integrating Chart in my app. Using https://github.com/danielgindi/Charts this have achieved: Expected Result: Code: let leftAxisFormatter = NumberFormatter() leftAxisFormatter.minimumFractionDigits = 0 leftAxisFormatter.maximumFractionDigits = 1 leftAxisFormatter.negativePrefix = " $" leftAxisFormatter.positivePrefix = " $" chartView.xAxis.gridLineDashPhase = 0 chartView.leftAxis.enabled = false chartView.xAxis.enabled = false let rightAxis = chartView.rightAxis rightAxis.enabled = true rightAxis.labelFont = .systemFont(ofSize: 10) rightAxis.labelCount = 4 rightAxis.valueFormatter = DefaultAxisValueFormatter(formatter: leftAxisFormatter) rightAxis.axisMinimum = 0 rightAxis.drawZeroLineEnabled=true rightAxis.labelPosition = .insideChart chartView.leftAxis.drawZeroLineEnabled = true chartView.legend.enabled = false chartView.leftAxis.drawAxisLineEnabled = false chartView.leftAxis.drawGridLinesEnabled = false chartView.rightAxis.drawAxisLineEnabled = false chartView.rightAxis.drawGridLinesEnabled = false chartView.xAxis.drawAxisLineEnabled = false chartView.xAxis.drawGridLinesEnabled = false let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] chartView.xAxis.valueFormatter = IndexAxisValueFormatter(values:months) chartView.xAxis.granularity = 1 What are other properties to achieve White vertical line on graph & Bottom Months in bottom. Thanks in advance.
use lineChart.xAxis.labelPosition = .bottom // LineChart lineChart.chartDescription?.enabled = false lineChart.dragEnabled = false lineChart.setScaleEnabled(false) lineChart.pinchZoomEnabled = false lineChart.rightAxis.enabled = false lineChart.legend.form = .default lineChart.legend.formSize = 0.0 lineChart.xAxis.axisMinimum = 0.0 lineChart.leftAxis.axisMinimum = 0.0 lineChart.xAxis.axisMaximum = 12.0 lineChart.leftAxis.axisMaximum = 100.0 lineChart.gridBackgroundColor = .clear lineChart.xAxis.labelPosition = .bottom lineChart.xAxis.labelFont = UIFont.RobotoRegularFontWithSize(size: 11) lineChart.xAxis.labelTextColor = UIColor.clear lineChart.leftAxis.labelTextColor = .clear lineChart.leftAxis.labelFont = UIFont.RobotoRegularFontWithSize(size: 11) lineChart.highlightPerTapEnabled = true lineChart.leftAxis.drawAxisLineEnabled = true lineChart.leftAxis.drawGridLinesEnabled = false lineChart.rightAxis.drawAxisLineEnabled = false lineChart.rightAxis.drawLabelsEnabled = false lineChart.xAxis.drawGridLinesEnabled = false lineChart.extraRightOffset = 15*screenWidthFactor lineChart.drawMarkers = true lineChart.pinchZoomEnabled = true lineChart.doubleTapToZoomEnabled = true
How to draw text parallel to Bar of BarChartView?
I am trying to achieve the functionality to show the win and loss percent of every month parallel to the bar. Please provide any suggestion. I am using danielgindi/Charts I am trying to achive the this functinality. here is the chart setup code: chartView.legend.enabled = true chartView.chartDescription?.enabled = false chartView.maxVisibleCount = 12 chartView.drawBarShadowEnabled = false chartView.drawValueAboveBarEnabled = false chartView.delegate = self chartView.dragEnabled = true chartView.doubleTapToZoomEnabled = false chartView.pinchZoomEnabled = true chartView.noDataTextColor = .black chartView.highlightFullBarEnabled = true chartView.drawGridBackgroundEnabled = false chartView.leftAxis.enabled = false chartView.leftAxis.drawGridLinesEnabled = false chartView.rightAxis.enabled = false chartView.rightAxis.drawGridLinesEnabled = false chartView.xAxis.enabled = true chartView.xAxis.drawGridLinesEnabled = false chartView.xAxis.drawAxisLineEnabled = false chartView.xAxis.labelPosition = .bottom chartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: months) chartView.xAxis.setLabelCount(months.count, force: false) chartView.xAxis.granularity = 1 let l = chartView.legend l.horizontalAlignment = .center l.verticalAlignment = .bottom l.orientation = .horizontal l.drawInside = false l.xEntrySpace = 5 l.yEntrySpace = 2 l.yOffset = 5 l.xOffset = 20 here i am assigning the value to chart let yVals = (0..<data.count).map { (i) -> BarChartDataEntry in let val1 = Double(data[i].ownopportunityOwn.roundToOneDigitCroreValue) let val2 = Double(data[i].ownopportunityAssistby.roundToOneDigitCroreValue) return BarChartDataEntry(x: Double(i), yValues: [val1, val2]) } let set = BarChartDataSet(values: yVals, label: "") set.drawIconsEnabled = false set.colors = [AppColors.Graph_LightGreenColor,AppColors.Graph_PurpleColor] set.roundedCorners = [.topLeft,.topRight] let data = BarChartData(dataSet: set) data.setValueFont(.systemFont(ofSize: 7, weight: .bold)) data.setValueFormatter(DefaultValueFormatter(formatter: formatter)) data.setValueTextColor(.white) chartView.fitBars = true chartView.data = data var array = [LegendEntry]() var legendValueArray = [(title: DashboardConstant.K_OWN_WINS.value, Color: AppColors.Graph_LightGreenColor),(title: DashboardConstant.K_ASSISTED_BY_WIN.value, Color: AppColors.Graph_PurpleColor)] for object in legendValueArray { array.append( LegendEntry(label: object.title, form: .square, formSize: 10, formLineWidth: 1, formLineDashPhase: 1, formLineDashLengths: nil, formColor: object.Color)) } self.chartView.legend.setCustom(entries: array) self.chartView.fitScreen() self.chartView.notifyDataSetChanged() chartView.animate(xAxisDuration: 3, yAxisDuration: 3)